Reputation: 2149
I have two following models:
class Student(models.Model):
name = models.CharField(max_length=255, help_text='Name of student')
class Group(models.Model):
name = models.CharField(max_length=255, help_text="Groups' name")
elder = models.ForeignKey(Student, default=None, blank=True, null=True)
The case is that I have form(created from modelForm) which is able to update entries in database. My problem is following:
User can create two groups with ForeignKey that will point to one entry in Student
table.
I've found db_constraint
in documentation but it seems like not enough.
It will be great to get following behavior:
When user assigns ForeignKey which is already assigned to another model, I want to delete old assignment and create new. So Student
Foreign key could be assigned only to one model at a time.
Upvotes: 0
Views: 65
Reputation: 53719
The OneToOneField
is specifically designed for unique relations:
class Group(models.Model):
name = models.CharField(max_length=255, help_text="Groups' name")
class Student(models.Model):
name = models.CharField(max_length=255, help_text='Name of student')
group = models.OneToOneField(Group, default=None, blank=True, null=True, related_name='elder')
Note how I moved the relationship field to the Student
model, this will give you the behaviour that you want. If it was on the Group
model, and you assign a student to a new group while he already has one, it would raise a DatabaseError
for violating the unique
constraint. In this case, the (unique) FOREIGN KEY
column is in the Student
's table, so if you assign a student to another group and save that group, the student table will be updated and the old group replaced.
Upvotes: 1
Reputation: 36
override the save
method of Group
:
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
Group.objects.filter(elder.self.elder).update(elder=None)
super(Group, self).save(force_insert, force_update, using, update_fields)
but you must use transactions to avoid inconsistency
Upvotes: 2