首页 > 解决方案 > Django 中的 .add() 方法未添加多对多关系条目

问题描述

我在向多对多关系字段添加条目时遇到问题。我的模型如下

class Address(models.Model):
    id = models.AutoField(primary_key=True)
    country = CountryField(blank_label='(select country)', blank=False, null=False, verbose_name='Country')
    state = models.CharField(
        max_length=50,
        choices=STATE_CHOICES,
        verbose_name='State',
        blank=False,
        null=False
    )
    ...

class Volunteer(models.Model):
    userID = models.OneToOneField(User, on_delete=models.CASCADE, to_field='id', primary_key=True, related_name='volunteer')
    identificationNumber = models.CharField(max_length=50, unique=True, blank=False, null=False, verbose_name='Identification   Number')
    currentAddress = models.ManyToManyField(Address, related_name='volunteerCurrentAddress', verbose_name='Current Address', blank=False)
    permanentAddress = models.ManyToManyField(Address, related_name='volunteerPermanentAddress', verbose_name='Permanent Address', blank=False)
    ...

    def save(self, *args, **kwargs):
        self.slug = self.userID.username
        super(Volunteer, self).save(*args, **kwargs)

class TemporaryVolunteer(Volunteer):
    pass

在视图中,我将currentAddresspermanentAddress字段都作为ManyToManyRelatedManager. 它们是temporaryVolunteer.currentAddresstemporaryVolunteer.permanentAddress。我用这些来创建一个新的志愿者实例

volunteer = Volunteer(...)
volunteer.save()
volunteer.currentAddress.add(temporaryVolunteer.currentAddress.all()[0])
volunteer.permanentAddress.add(temporaryVolunteer.permanentAddress.all()[0])
volunteer.save()

但是当我做print(volunteer.currentAddress.all())or时print(volunteer.permanentAddress.all()),它返回一个空的查询集。我还检查了管理站点进行确认,志愿者实例上没有地址条目。有什么办法可以用这种方法添加条目?

标签: djangomany-to-many

解决方案


问题在于数据库的设计。我使用了一个新班级TemporaryVolunteer来存储未经验证的帐户,后来Volunteer在他们被验证后转移到班级。TemporaryVolunteer正如我从课堂上继承Volunteer的那样,Django 处理多对多关系而不重复的方式(来源:https ://docs.djangoproject.com/en/3.0/topics/db/examples/many_to_many/ )导致了 no 的问题条目被添加到相应的Volunteer类中。

最初,我通过复制 to 的所有成员Volunteer来检查这一点TemporaryVolunteer。在验证它是否有效后,我更改了数据库设计,因为这是一种不好的方法,并isVerified在类中保留了一个布尔值Volunteer并完全删除了TemporaryVolunteer该类。


推荐阅读