I have a Tournament model with related Standings:
class Tournament(models.Model):
standings = models.ForeignKey('Standings', blank=True, null=True)
I just did the following:
standings = Standings.objects.get(pk=pk)
standings.delete()
And it deleted the related tournament as well. This should not have happened, since standings is a nullable field.
Why did it happen and what can I do to prevent this from happening again?
Django 1.8 defaults to CASCADE:
When an object referenced by a ForeignKey is deleted, Django by default emulates the behavior of the SQL constraint ON DELETE CASCADE and also deletes the object containing the ForeignKey.
To change that behavior, you should add the on_delete argument (mandatory as of Django 2.x) as follows:
standings = models.ForeignKey(
'Standings', blank=True, null=True, on_delete=models.SET_NULL)
Related
We have two Django models:
class Project(models.Model):
project_title = models.CharField(max_length=30)
owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING)
class User(models.Model):
usernmae = models.CharField(max_length=50)
active_project = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING, related_name='current_project')
I have a user with object (with id say 692). And this user created a project with id=12345, therefore these owner field will get have this particular referenced.
I want to delete that user. But it shows error that
delete on table "app_user" violates foreign key constraint
This is expected as on_delete=models.DO_NOTHING, was set. One way I found out was using on_delete=models.CASCADE.
Question: How should I go about deleting the user (692) without changing the model definition(having to re-run migration)?
Doing it manually by deleting the project first, leads to the same foreign-key error, as owner field is User object.
How to handle this mutual foreign key relationship while deleting, as deleting any one of those two throws the foreign-key exception?
Update
Some correction in the model definition username is the field name instead of usernmae (typo). And the foreignkey for project is Project not the User model.
class Project(models.Model):
project_title = models.CharField(max_length=30)
owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING)
class User(models.Model):
username = models.CharField(max_length=50)
active_project = models.ForeignKey(Project, null=True, on_delete=models.DO_NOTHING, related_name='current_project')
IF you really don't want to make a migration (any specific reason?) and if you are ok with doing this manually this time. Then you have two options:
Go into the admin panel and manually change the User field in the project instance to a different user or to NULL. Now you should be able to delete the User instance since it's not referred anymore into the project.
If that worked, you can then delete the project instane as well.
Curios if this will work, let me know!
When creating a new "Cast" record via the Django admin, I'm told "image_cover" attribute is null, but that attribute isn't even a part of the "Cast" model. Why would this happen?
The Error:
django.db.utils.IntegrityError: null value in column "image_cover" violates not-null constraint
DETAIL: Failing row contains (33, 1, null).
Details
While "image_cover" is NOT part of the "Cast" model, it is a charfield on the "Book" model (foreign key). However the error occurs despite "image_cover" being null=True
I've tried...
I have not modified the Create function built into Django. and I have run makemigrations and migrate to ensure the database was up to date with models.py. And I have restarted my server to ensure the changes took effect.
Notice that the only value being reported as null in the failing row might be the "aliases" field despite the fact that I did define several alias objects as part of the "Cast" creation.
Here are the Models we are dealing with (models.py)
class Cast(models.Model):
name = models.CharField(max_length=255, default='The Original Cast')
book = models.ForeignKey('Book', on_delete=models.CASCADE)
aliases = models.ManyToManyField('CharacterAlias', blank=True, related_name='casts')
class Book(models.Model):
title = models.CharField(max_length=255, default='')
author = models.CharField(max_length=255, default='')
image_cover = models.CharField(max_length=1555, default='', blank=True, null=True)
# some unrelated other stuff...
I have two models (Slot, Appointment). On the appointment one, I have defined a OneToOne relation with the slot model, so good so far; thanks to the RelatedManager I can access the appointment from the slot object but this's done at python level and I need (for some future changes) appointment_id column to be created on the Slot table.
class Slot(models.Model):
start_at = models.DateTimeField()
end_at = models.DateTimeField()
duration = DateTimeRangeField(
null=True,
blank=True
)
# Bidirectional
appointment = models.OneToOneField(
"appointments.Appointment",
on_delete=models.SET_NULL,
related_name="slot",
blank=True,
null=True
)
class Appointment(models.Model):
slot = models.OneToOneField(
Slot,
on_delete=models.SET_NULL,
related_name="appointment",
null=True,
blank=True,
)
The code above will raise some errors when trying to create the migrations like:
appointments.Appointment.slot: (fields.E302) Reverse accessor for 'Appointment.slot' clashes with field name 'Slot.appointment'.
HINT: Rename field 'Slot.appointment', or add/change a related_name argument to the definition for field 'Appointment.slot'.
Basically, due to the python part of the ORM, you can't define the same field on both models.
Any idea of how to achieve this. I guess I will have to overwrite some parts of the RelatedManager. I could make this throw SQL but then it won't be clear on the code level.
I have a field
owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
What is the difference between these two attributes on model field ?
null=True means owner field can be null in the database which means you can make an object of your model that has no owner.
on_delete=models.SET_NULL
means if the owner of an existing object got deleted set this field for existing object to null.
null=True means that the field could be empty or null, but on_delete=models.SET_NULL is being used to take of the presence of the owner of the field, that it should be set to NULL if the owner is not present.
class Product(models.Model):
name = models.CharField(max_length = 50)
category = models.ForeignKey(Category, on_delete=models.SET_NULL)
SET_NULL argument of the ForeignKey on_delete option is only available to you when you have set the null option on the ForeignKey field to True.
After use null=True and on_delete=models.SET_NULL, when a deletion happens to the referenced object then the value of the referencing object will be updated as NULL. So a NULL value will be placed for the referencing object.
I have the following sample models:
class Note(models.Model):
text = models.TextField()
author = models.OneToOneField(User)
date_created = models.DateField(auto_now_add=True)
similar_note = models.ForeignKey("self", related_name='similar_note', null=True, blank=True)
Say there are two notes Winner and Loser.
Loser has a field similar_note that points to Winner Note.
When I delete any of the two, both gets deleted, how do I prevent this from happening?
I have tried doing the same from the django admin interface as well, it happens from there as well.
PS: I am using django1.2, please don't advice to upgrade, there are way too many constraints.
As mentioned here:
When Django deletes an object, by default it emulates the behavior of
the SQL constraint ON DELETE CASCADE -- in other words, any objects
which had foreign keys pointing at the object to be deleted will be
deleted along with it.
This cascade behavior is customizable via the on_delete argument to
the ForeignKey
Please check the on_delete parameter for model field:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)