Django模型保存相关模型

时间:2017-10-30 03:43:03

标签: django

我有三个模特,人,角色和学生。 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信号也可以实现这一点,但我不确定是怎么做的。

感谢。

1 个答案:

答案 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)

所有代码都未经过测试。