我有三个模特,人,角色和学生。 Person与ManyToManyField的角色相关,Student继承自Person。代码:
class Person(models.Model):
#fields
class Role(models.Model):
ROLE_CHOICES = (
('AL', 'ALUMNO'),
#... more choices
)
person = models.ManyToManyField(Person)
role = models.CharField(
'Rol',
max_length = 2,
choices = ROLE_CHOICES
)
class Student(Person):
# fields
def save(self, *args, **kwargs):
super(Student, self).save(*args, **kwargs)
# what code should I put here to save role?
我想在保存学生时自动为他/她保存一个角色('AL')。此外,它必须在创建而不是更新时执行。
我已经看过其他帖子,但我仍然不清楚如何 实现这一点。
据我了解,我可以覆盖save
方法,但我不确定这是怎么做到的。我知道post_save
信号也可以实现这一点,但我不确定是怎么做的。
感谢。
答案 0 :(得分:2)
在学生通过save方法获取pk之前,你不能这样做,因为m2m关系是由你的实例pk建立的,pk是在你的实例保存到db之后生成的。 两种方式:
第一个:
您应用中的新signals.py
个文件:
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import *
@receiver(post_save, sender=Student)
def create_student(sender, instance=None, created=False, **kwargs):
if created:
role, is_created = Role.objects.get_or_create(name='AL')
role.person.add(instance)
并在apps.py
class UserConfig(AppConfig):
name = 'user'
def ready(self):
import user.signals
将User
替换为您自己的app_label
。
第二个:
在django 1.9之后,django有交易工具允许你在commit.doc为here之后执行操作:
from django.db import transaction
class Student(Person):
.
.
.
def save(self, *args, **kwargs):
instance = super(Student, self).save(*args, **kwargs)
if not self.pk:
# do when create
transaction.on_commit(self.update_role)
return instance
def update_role(self):
# this will be call after instance save to db
role, is_created = Role.objects.get_or_create(name='AL')
role.person.add(self)
所有代码都未经过测试。