如何确保Django中许多领域的独特性

时间:2015-01-19 02:02:48

标签: django python-3.x django-models

所以说你有以下模特:

class User(models.Model):

class Tag(models.Model):
    text = models.CharField(unique=True)

class Subscription(models.Model):
    owner = models.ForeignKey(User)
    tags = models.ManyToManyField(Tag)
    class Meta:
        unique_together = (("owner", "tags"),)

class Post(models.Model):
    owner = models.ForeignKey(User)
    tags = models.ManyToManyField(Tag)

从上面可以看出,用户可以根据标签进行订阅。理想情况下,您希望确保用户的每组订阅都是唯一的吗?这就是我将unique_together添加到元类的原因。但是我收到了这个错误:

Subscription: (models.E013) 'unique_together' refers to a ManyToManyField 'tags', but ManyToManyFields are not permitted in 'unique_together'.

有什么想法吗? THX。

1 个答案:

答案 0 :(得分:2)

您无需指定unique_together。 Django中的ManyToManyField默认是唯一的。尝试两次添加相同的关系,您将看到只有一条记录。

我已为此修改了一个有用的Django Snippet

from django.db import models
from django.db.models.signals import m2m_changed
from django.dispatch import receiver
from django.db.utils import IntegrityError

class User(models.Model):
    pass

class Tag(models.Model):
    text = models.CharField(unique=True)

class Subscription(models.Model):
    owner = models.ForeignKey(User)
    tags = models.ManyToManyField(Tag)
    class Meta:
        unique_together = (("owner", "tags"),)

class Post(models.Model):
    owner = models.ForeignKey(User)
    tags = models.ManyToManyField(Tag)

@receiver(m2m_changed, sender=Subscription.tags.through)
def verify_uniqueness(sender, **kwargs):
    subscription = kwargs.get('instance', None)
    action = kwargs.get('action', None)
    tags = kwargs.get('pk_set', None)

    if action == 'pre_add':
        for tag in tags:
            if Subscription.objects.filter(owner=subscription.owner).filter(tag=tag):
                raise IntegrityError('Subscription with owner %s already exists for tag %s' % (subscription.owner, tag))