django - Django UniqueConstraint 不适用于 ManyToManyField,出现异常 FieldDoesNotExist
问题描述
ForeignKey
从Shop
和切换user
到ManyToManyField
. 我希望商店能够同时由不同的用户拥有:
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
吗?
解决方案
问题
UniqueConstraint
on将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
字段ManyToManyField
从ForeignKey
注意:我把字段名改成了from ,这样比较合适。users
user
方法一:移除唯一约束
class Shop(models.Model):
name = models.CharField('name', max_length=120)
users = models.ManyToManyField(User)
现在,运行makemigrations
和migrate
命令
方法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)