I have a model called SimplePage in which I have this line:
category = models.ForeignKey('Category', related_name='items',
blank=True, null=True)
I assumed this will allow me to have SimplePage instances that do not have a Category.
But for some reason, when I try to create a SimplePage in the Admin with no Category, I get:
IntegrityError at /admin/sitehelpers/simplepage/add/
sitehelpers_simplepage.category_id may not be NULL
What is this?
Could it possibly be that you added the null=True attribute after doing the syncdb for that model? Django won't change database tables, only create them. Check in your database if NULL is allowed for that column and change it manually.
Edit: starting with Django 1.7, this answer and the comments are not really valid anymore, since Django gained a fully featured migration framework.
Related
I am new to django and I am facing some problem.
This was my previous model.
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
I added some data to this model.
After that I added one more field to it.
Now my model looks like this..
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
age = models.IntegerField()
When I ran the command python manage.py makemigrations I got the following error which is obvious.
You are trying to add a non-nullable field 'age' to blog without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
I don't want to add default so I deleted the table contents by accessing db.sqlite3
But again after running python manage.py makemigrations I am getting the same error.why?
Even though you have deleted the table, any changes to your Django model will always refer to the previous migration of that model, hence it still requires you to set a default value. If you're still in development, then you could delete the migrations for that model and then makemigrations again. But, this is terrible practice and you should never do this unless you are consciously squashing your models, the better way is to do what Django is telling you and set a default. This'll help in the long run anyways with error handling.
The other answers address how to set defaults quite well.
When you add a new field (i.e., column) to a database table, that field applies to all rows in the table...the existing ones and any new ones. If the field cannot be null, then some value must be specified for all of the existing rows.
By default, IntegerField() is non-nullable. This explains why you are getting the warning. You have a few options:
You can choose a default "one-off" initial value like Django suggests. All existing rows will use this value for the new field.
Assign your own values to each existing row for the new field.
Use the blank and null arguments in your model field to allow the field to accept null values.
For the last option, you'd do this like so:
models.IntegerField(blank=True, null=True)
But that might not be the best choice depending on your use case. If nullable values don't make sense for your field, I would avoid making the field support nulls.
age = models.IntegerField(null=True)
Django models fields are null set to true by default.
The way you can solve this:
Delete the Blog table from the database.
Delete the migrations folder from the app that contains Blog model.
Remove all data from django_migrations table.
Now run makemigrations and then migrate command.
Hope this will solve your problem.
Do what Django is telling you, then you can remove the default attribute if you don't need it. But it's a good practice to keep it anyway
Say we're building a Django-based site that clones Medium.com's URL structure, where you have users and articles. We'd probably have this model:
class Article(models.Model):
user = models.ForeignKey(User)
slug = models.CharField()
We want to be able to build URLs that look like /<username>/<slug>/. Since we're going to have billions of articles and zillions of pageviews, we want to put an index on that model:
class Meta:
indexes = [
models.Index(fields=['user__username', 'slug'])
]
But this causes the makemigrations command to fail with the following error:
django.core.exceptions.FieldDoesNotExist: Article has no field named 'user__username'. The app cache isn't ready yet, so if this is an auto-created related field, it won't be available yet.
So, plain vanilla models.Index doesn't support relational lookups like a QuerySet does. How would I add an index like this? Let's assume PostgreSQL, if that's helpful.
It seems that you can't make multi-table index according to this answer.
So if it's not possible in the database, I don't see how can Django offer this feature...
What you can do to make your queries more efficients is an index using user_id and slug.
Django index meta class mainly provide declarative options for indexing table fields,
you can create an index using several field of a model or create different index for every fields of the model. you just don't have to provide user foriegnkey field name attribute which generate automatic user_id index migrations
migrations.AddIndex(
model_name='candidates',
index=models.Index(fields=['user'], name='candidates__user_id_569874_idx'),
),
you can also set the index name in the model meta, and db_tablspace as well if needed.
I am using model inheritance in my models.py. This is my code:
class Email(models.Model):
stuff = models.CharField(max_length=40, blank=True,
null=True, default="")
class TypeMod(Email):
pass
When I run makemigrations, I get the following message although I have set the default value for all of my fields in the Email model:
You are trying to add a non-nullable field 'id' to typemod without a
default; we can't do that (the database needs something to populate
existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows
with a null value for this column)
2) Quit, and let me add a default in models.py
What am I doing wrong?!
It doesn't necessarily have to do with vagrant. I used a native Linux machine and got the same message. My solution was to remove the existing migrations.
Well I figured it out! For anyone who has the same issue, I am using vagrant and this project is running on a vm.So the problem was that the parent model was not abstract before, so a table was made in the database for the parent model. So when I switched to abstract, the table was still there. The way I solved it was that I ran "vagrant distroy" and restarted the vm.
I have a DateTimeField in one of my Django models.
completed_date = models.DateTimeField('date completed', blank=True, null=True)
I've defined it to allow blank and null values. However, when I try to create an instance of the model, I get the following error:
IntegrityError at
/admin/tasks/project/add/
tasks_project.completed_date may not
be NULL
I'm using Django 1.25 and Python 2.7. Anyone know why this is happening? Is there anything I can do to fix this?
I found a ticket that describes the same problem, but it was closed as fixed 4 years ago, so I assume it must have been integrated into Django by now!
django syncdb and an updated model
from that question/answer:
Django doesn't support migrations out
of the box. There is a pluggable app
for Django that does exactly that
though, and it works great. It's
called South.
http://south.aeracode.org/
Havent used django in a while, but i
seem to remember that syncdb does
perform alter commands on db tables.
you have to drop the table then run
again and it will create again.
Some model fields such as DateTimeField require null=True option when blank=True option is set.
I'd like to know which fields require that (maybe dependent on backend DBMS), and there is any way to do this automatically.
This post should help to understand the difference on blank and null in Django
null=True is used to tell that in DB value can be NULL
blank=True is only for django , so django doesn't raise error if field is blank e.g. in admin interface
so blank=True has nothing to do with DB
NULL requirement will vary from DB to DB, and it is upto you to decide if you want some column NULL or not