【问题标题】:How to ensure uniqueness in manytomany fields in Django如何确保 Django 中多字段的唯一性
【发布时间】:2015-01-19 02:02:47
【问题描述】:

假设您有以下模型:

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'.

有什么想法吗?谢谢。

【问题讨论】:

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


    【解决方案1】:

    你不需要指定 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))
    

    【讨论】:

    • 这不能回答问题,因为 OP 需要 Usertags 通过 Subscription 模型的集合的唯一性
    • 啊,我误读了这个问题。感谢您指出了这一点。我已经更新了答案。
    • 感谢您的回复!我认为这是我想要的正确方向。 :) 这里有细微差别。这不是我关心的重复标签。我想确保集合是独一无二的。因此,当我想在订阅中插入一组新标签时,最好确定新组是否唯一,并且只有在这种情况下才插入新组。
    猜你喜欢
    • 2011-11-17
    • 2021-02-20
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    相关资源
    最近更新 更多