【问题标题】:Django admin model relationshipDjango 管理模型关系
【发布时间】:2019-09-19 16:38:15
【问题描述】:

所以,我正在建立一个 Store 网站,我有 2 个应用程序,一个名为 Store 的应用程序,它有两个模型“Store”和“UnitStore”。第二个应用名为 Product,而它有一个名为 Store 的模型。

在产品管理中,我使用 formfield_for_foreignkey 方法来显示 StoreUnit 和 Store,如下所示:“Store_name | Unit_name”

所以,我的问题是,当我尝试创建产品时,它总是要求 UnitStore 的外键,但并非所有产品都来自 UnitStore,有些产品只能在 Store 中找到,因此,我不是能够创建一个实例。

- 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)

我是否应该向 Product 模型添加另一个外键,如下例所示。因此我应该能够通过以下方式访问产品: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,
    )

【问题讨论】:

  • 示例中的 UnitStore 类实际上应该是 StoreUnit 吗?如果没有,请您分享 StoreUnit 模型
  • 您好,感谢您与我们联系!那么,Store 和 UnitStore 都属于 Store Models。

标签: django django-admin django-orm django-admin-filters django-admin-tools


【解决方案1】:

您需要有一个同时捕获商店和单元商店的商店模型,并且它的 __str__ 方法应该始终打印主商店名称和单元商店名称(如果适用):

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

一旦你有了这样的模型,你就可以让一个外键指向一个商店或一个单位商店。

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,
    )

【讨论】:

  • 您好,感谢您与我们联系!我也这么认为,但问题是,在产品管理中,我使用 formfield_for_foreignkey 方法来覆盖“store_unit_name”字段以显示单元名称,如下所示:“Store_name | Unit_name”,即:“Store One |纽约单位”。我通过将属性 null=True 添加到 Product > store 外键,因此,在 Product > Admin.py 中,我可以将两个字段都添加到字段集中:“store_unit_name”和“store”,最后,如果产品来自一个 Unit Store 我选择“store_unit_name”,否则选择“store”。
  • 如果你想改变存储单元在管理表单中的显示方式,只需在UnitStore 模型中实现__str__() 方法。 docs.djangoproject.com/en/2.2/ref/models/instances/#str您不需要自定义表单字段。
  • 当然,我知道,但不幸的是,这并不能解决我的问题,我的意思是,并非所有产品都来自 UnitStore 模型,有些来自没有 UnitStore 的商店。那么,当我没有 UnitStore 时,我现在如何在管理表单中显示商店名称,我正在使用“obj.store.store_name”
  • 那么,如果我在 Product 模型中添加另一个外键,就像上面的示例一样:但是查询不是太多吗?
  • 如果是这种情况,我认为您需要更改模型。我可以建议对模型进行规范化,而不是使用StoreUnitStore,而是使用Store,并带有对父Store 的可为空引用。所有具有父级的商店都是unit_store,在商店的__str__ 中,您可以输出名称或主商店和单元商店的名称。