So, I am building a Store website, I got 2 apps, one app called Store, it has two models "Store" and "UnitStore". The second app is called Product whereas it got single models called Store.
In Product admin, I am using a formfield_for_foreignkey method to show StoreUnit and Store like this: "Store_name | Unit_name"
So, my problem is that when I try to create a product, it always ask for a UnitStore's foreign key, but not all products comes from a UnitStore, some product can only be found in a Store, therefore, I am not able to create a instance.
- Store > Models.py
class Store(models.Model):
store_name = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.store_name
class UnitStore(models.Model):
store_unit_name = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
store = models.ForeignKey(
Store,
related_name='units',
on_delete=models.CASCADE,
)
def __str__(self):
return self.store_unit_name
Product > Models.py
class Product(models.Model):
product= models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
store_unit_name = models.ForeignKey(
StoreUnit,
related_name='units',
on_delete=models.CASCADE,
)
def __str__(self):
return self.product
- Product > Admin.py
class CustomProduct(admin.ModelAdmin):
model = Product
list_display = ('product', 'created_at', 'aupdated_at',
'store_unit_name',)
list_select_related = ('store_unit_name')
fieldsets = (
("Prodcut's Name:", {
'fields': ('product',)}),
('Store:', {
'fields': ('store_unit_name',)}),
)
def save_model(self, request, obj, form, change):
obj.created_by = request.user
super().save_model(request, obj, form, change)
Should I add another foreign key to the Product models, like the example below. therefore I should be able to access the Product by: product.store.store_name.
class Product(models.Model):
product= models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
store_unit_name = models.ForeignKey(
StoreUnit,
related_name='units',
on_delete=models.CASCADE,
)
store= models.ForeignKey(
Store,
related_name='stores',
on_delete=models.CASCADE,
)
You need to have a Store model that captures both stores and unit stores and its __str__
method should print the main store name always and the unit store name if applicable:
class Store(models.Model):
store_name = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
main_store = models.ForeignKey(
'Store',
null=True,
related_name='units',
on_delete=models.CASCADE,
)
def __str__(self):
ret_value = self.main_store.store_name + " | " if self.main_store else ""
return ret_value + self.store_name
Once you have the model like this you can just have a single foreign key pointing at either a store or a unit store.
class Product(models.Model):
product = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
store= models.ForeignKey(
Store,
related_name='products',
on_delete=models.CASCADE,
)