如何建模两个关系,并强制该对是唯一的

时间:2016-11-03 01:50:27

标签: django django-rest-framework

我有一个像这样的DRF模型:

class Party(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    name = models.CharField(unique=True, blank=False, null=False)

两个也只有两个派对可以形成一个整合,我目前已经模仿了这个:

class Integration(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    party_a = models.ForeignKey('Party')
    party_b = models.ForeignKey('Party')
    class Meta:
        managed = True
        unique_together = (('party_a', 'party_b'), ('party_b', 'party_a'))

party_aparty_b对必须是唯一的;哪一方无所谓。因此,党123和党456只能整合一次。 unique_together在这里对我没什么帮助,所以我设置了一个验证器来做到这一点。

class IntegrationSerializer(serializers.HyperlinkedModelSerializer):
    party_a = serializers.PrimaryKeyRelatedField(queryset=Party.objects.all())
    party_b = serializers.PrimaryKeyRelatedField(queryset=Party.objects.all())

class Meta:
    model = Integration
    fields = ('id', 'party_a', 'party_b', 'enabled', 'active_date')

def validate(self, data):
    if len(Integration.objects.filter(party_a=data['party_a'], party_b=data['party_b'])) > 0 or \
                    len(Integration.objects.filter(party_a=data['party_b'], party_b=data['party_a'])) > 0:
        raise serializers.ValidationError('Integration already exists')
    return data

我想知道这是否是建立这种关系的最佳方式?我目前的解决方案似乎工作正常,但在我测试时,我一直在寻找需要修复的东西。就像我忘了验证器会在PUT上触发。

任何建议都表示赞赏......

1 个答案:

答案 0 :(得分:0)

比较party_a和party_b,将小一个放在party_a中,将大一个放在party_b中。这使得db中只存在一对实例。您可以覆盖序列化程序的save方法以确保这种关系。

P.S。 queryset.count似乎比len(queryset)更优雅,在这里你可以使用queryset.exists。