The migration stopped working when switching from ForeignKey
between Shop
and user
to a ManyToManyField
. I wanted shops to be able to be owned by different users at the same time:
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 has no field named 'shopusers'
I thought by choosing a related name I can use multiple relations to the User
model? I already tried completely deleting my database (and migrations folder) and migrate from start, but tht did not help :(
Example where I would call the code:
admin.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
Where does Djanog migrations get the NewShop
from FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
? Is it automatically generated from the ModelName Shop
?
The UniqueConstraint
on ManyToManyField
will not work as expected. If you want to enforce the constraint, you should define a intermediate model and connect them using the through
--(Django doc) parameter.
For the sake of simplicity, I assume you have a model as below,
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!'
)
]
and now you want make the user
field to a ManyToManyField
from ForeignKey
Note: I have changed the field name to users
from user
, which is more approriate.
class Shop(models.Model):
name = models.CharField('name', max_length=120)
users = models.ManyToManyField(User)
Now, run makemigrations
and migrate
commands
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)