首页 > 解决方案 > Django UniqueConstraint 不适用于 ManyToManyField,出现异常 FieldDoesNotExist

问题描述

ForeignKeyShop和切换userManyToManyField. 我希望商店能够同时由不同的用户拥有:

class Shop(models.Model):
    name = models.CharField('name', max_length=120)
    #user = models.ForeignKey(User, on_delete=models.CASCADE)   ##before
    shopuser= models.ManyToManyField(User, related_name="shopusers", blank=True)    ##after

    class Meta:
        constraints = [models.UniqueConstraint(fields=['shopuser', 'name'], name='user cant have the same shop twice!')] 
    
    ## after:
    @property
    def get_shopuser(self):
        return ", ".join([u.username for u in self.shopuser.all()])

class Warehouse(models.Model):
    address = models.CharField('address', max_length=120)
    user = models.ManyToManyField(User, related_name="User", blank=True)

django.core.exceptions.FieldDoesNotExist:NewShop 没有名为“shopusers”的字段

我想通过选择一个相关的名称,我可以使用与User模型的多个关系?我已经尝试完全删除我的数据库(和迁移文件夹)并从头开始迁移,但没有帮助:(

我将调用代码的示例:

管理员.py:

@admin.register(Shop)
class ShopAdmin(admin.ModelAdmin):
    list_display = ("name", "related_shopuser")
    list_filter = ("name", "shopuser")
    fieldsets = [("Requrired Information", {"description": "These fields are required", 
                                            "fields": (("name", "shopuser"))}),]

    def related_shopuser(self, obj):
        return obj.get_shopuser

Djanog 迁移NewShop从哪里获得FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))?它是从 ModelName 自动生成的Shop吗?

标签: djangodjango-modelsdjango-migrations

解决方案


问题

UniqueConstrainton将ManyToManyField无法按预期工作。如果要强制执行约束,您应该定义一个中间模型并使用through--(Django doc)参数连接它们。

为了简单起见,我假设您有一个如下模型,

class Shop(models.Model):
    name = models.CharField('name', max_length=120)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=[
                    'user',
                    'name'
                ],
                name='user cant have the same shop twice!'
            )
        ]

现在你想让这个user字段ManyToManyFieldForeignKey

注意:我把字段名改成了from ,这样比较合适。usersuser

方法一:移除唯一约束

class Shop(models.Model):
    name = models.CharField('name', max_length=120)
    users = models.ManyToManyField(User)

现在,运行makemigrationsmigrate命令

方法2:使用中间模型

class ShopUserIntermediateModel(models.Model):
    shop = models.ForeignKey('Shop', models.CASCADE)
    user = models.ForeignKey(User, models.CASCADE)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=[
                    'shop',
                    'user'
                ],
                name='user cant have the same shop twice!'
            )
        ]


class Shop(models.Model):
    name = models.CharField('name', max_length=120)
    users = models.ManyToManyField(User, through=ShopUserIntermediateModel)

推荐阅读