django获取现有对象并更新m2m

时间:2017-03-15 09:45:07

标签: django django-rest-framework many-to-many

models.py

class PhoneNumber(models.Model):
    person = models.ManyToManyField(Person, related_name='phonenumbers', blank=True)
    employee = models.ManyToManyField(Employee, related_name='phonenumbers', blank=True)
    phone = models.CharField(max_length = 20)

为了检查是否存在手机,我尝试为PhoneNumber模型创建save()方法:

def save(self, *args, **kwargs):
     #check if phone exists
     exist_phone = PhoneNumber.objects.filter(phone=self.phone).last()
     if exist_phone:
         new_people = self.person
         if new_people:
             for person in new_people:
                 exist_phone.person.add(person)
         new_employees = self.employee
         if new_employees:
             for employee in new_employees:
                 exist_phone.employee.add(employee)
     else:
         super(PhoneNumber, self).save(*args, **kwargs)

由于发生错误,它无法正常工作:

"<PhoneNumber: >" needs to have a value for field "phonenumber" before this many-to-many relationship can be used.

但我希望获得现有对象并为m2m添加新值。如何从已发布的m2m字段中获取值?是否有可能在模型中实现它?

更新

在模型中无法实现这一点。 我使用drf并在序列化器中实现了get_or_create

class PhoneNumberSerializer(serializers.ModelSerializer):

    class Meta:
        model = PhoneNumber
        fields = ('id', 'person', 'employee', 'phone')

    def create(self, validated_data):
        people = validated_data.pop('person')
        employees = validated_data.pop('employee')
        phone = validated_data['phone']
        exist_phone = PhoneNumber.objects.filter(phone=phone).last()

        if exist_phone:
            phonenumber = exist_phone
            for person in people:
                person.phonenumbers.add(phonenumber)
            for employee in employees:
                employee.phonenumbers.add(phonenumber)
        else:
            phonenumber = PhoneNumber.objects.create(**validated_data)

        return phonenumber

这不是很方便,因为你需要为drf和admin以及其他表单做同样的事情。

1 个答案:

答案 0 :(得分:0)

在这种情况下你应该使用Signal因为M2M字段可以在创建实例后保存。

我认为你使用post_save

我建议你阅读这份文档。 https://docs.djangoproject.com/en/1.10/ref/signals/#django.db.models.signals.post_save