django table onlineshop_product has no column named name

Viewed 627

I work on an online shopping website project with the help of Django. and I'm a beginner in Django The following code provides a table of my database. It helps to add a product.

class Product(models.Model):
    category = models.ForeignKey(Category,related_name='products', on_delete=models.CASCADE)

    name = models.CharField(max_length=200,db_index=True)
    slug = models.SlugField(max_length=200,db_index=True)
    image = models.ImageField(upload_to='products/%y/%m/%d',blank=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

Shows me an error in the browser. This error shows me when I add a product inside the admin panel. It helps to add a product but when I add the product the following error occurs.

OperationalError at /admin/onlineshop/product/add/

table onlineshop_product has no column named name

When I did migration using the command:

python manage.py migrate

It shows:

Operations to perform: Apply all migrations: admin, auth, contenttypes, onlineshop, sessions Running migrations: No migrations to apply. Your models in app(s): 'onlineshop' have changes that are not yet reflected in a migration, and so won't be applied. Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

python manage.py makemigrations

It is impossible to add the field 'created' with 'auto_now_add=True' to product without providing a default. This is because the database needs something to populate existing rows.

  1. Provide a one-off default now which will be set on all existing rows
  2. Quit and manually define a default value in models.py. Select an option:

How to solve it?

2 Answers

It is well-known issue, refer here[django-doc] for this, it will be easy if you choose 1st option.

Choose 1st option:

Then, you will be shown something like this in your shell:

Select an option: 1
Please enter the default value now, as valid Python
You can accept the default 'timezone.now' by pressing 'Enter' or you can provide another value.
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
[default: timezone.now] >>>

Here, simply press Enter the field will be added to migration and your work is done then simply run migrate command. You can also check it in migration file.

Migration file

operations = [
        migrations.AddField(
            ....
            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
        )
    ]

Edit:

Try this:

name = models.CharField(max_length=200,db_index=True,default='any_name')

Then run makemigrations and migrate.

Change your Product(...) class like this:

from django.db import models
from datetime import datetime

class Product(models.Model):
    # ... all other fields
    name = models.CharField(max_length=200, db_index=True, default='Name not provided')
    created = models.DateTimeField(auto_now_add=True, null=True)
    updated = models.DateTimeField(auto_now=True, null=True)

and run these commands in sequence:

python manage.py makemigrations your_app_name # app name is optional parameter if you have app then provide app name
python manage.py migrate

Although settings null = True is bad idea but this will solve your problem for now but if you want to fix this issue you can follow this post or this answer.

Update

If above solution is not working or facing some issue then do like this:

Note : In this approach you've to delete you database (sqlite).

Step - 1

Delete __pycache__ & migrations folders from all of your apps

Step - 2

Delete db.sqlite3

Step - 3

Run makemigrations & migrate commands as mentioned above.
Related