Django - 在管理面板中显示具有内容类型的模型

Posted

技术标签:

【中文标题】Django - 在管理面板中显示具有内容类型的模型【英文标题】:Django - Displaying model having content type in admin panel 【发布时间】:2019-04-27 09:35:21 【问题描述】:

我是 Django 新手,我遇到了一个问题。我有多个模型需要地址和电话号码与地址。并且只有电话号码可以与某些型号关联。因此,我为“Addresses”和“PhoneNumber”建立了多态关系。喜欢这里:

class PhoneNumber(SoftDeleteModel):
     phone_number = PhoneNumberField()
     content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
     object_id = models.PositiveIntegerField()
     content_object = GenericForeignKey('content_type', 'object_id')
     created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
     updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
     created_by = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)

     def __str__(self):
         return self.phone_number.as_e164

class Address(SoftDeleteModel):
     house_number = models.CharField(max_length=255)
     street_number = models.CharField(max_length=255)
     area = models.CharField(max_length=255)
     city = models.CharField(max_length=255)
     country = models.CharField(max_length=255)
     content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
     object_id = models.PositiveIntegerField()
     phone_number = GenericRelation(PhoneNumber)
     content_object = GenericForeignKey('content_type', 'object_id')
     created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
     updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
     created_by = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)

     def __str__(self):
          return str(self.house_number)+", "+str(self.street_number)+", "+self.area+", "+self.city+", "+self.country

这些是 AddressPhoneNumber 的模型我在 Vendor 中使用 Address 模型,例如:

class Vendor(SoftDeleteModel):
     vendor_name = models.CharField(max_length=500)
     vendor_phone = GenericRelation(PhoneNumber)
     vendor_address_detailed = GenericRelation(Address)
     vendor_contact_person = models.CharField(max_length=500)
     created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
     updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)
     created_by = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)

     def __str__(self):
          return self.vendor_name

当我在管理员中为供应商创建 crud 时,我只能在 Address 模型中获得 Addresses 而不是 PhoneNumber ,如图中所示

管理类的代码如下:

class PhoneNumberAdmin(GenericTabularInline):
     model = PhoneNumber
     extra = 1
     exclude = ('deleted', 'created_by')

     def save_model(self, request, obj, form, change):
         obj.created_by = request.user
         super().save_model(request, obj, form, change)


class AddressAdmin(GenericStackedInline):
     model = Address
     extra = 1
     exclude = ('deleted', 'created_by')

     def save_model(self, request, obj, form, change):
         obj.created_by = request.user
         super().save_model(request, obj, form, change)


class VendorAdmin(admin.ModelAdmin):
     model = Vendor
     list_display = ('vendor_name', 'created_by', 'created_at_readable')
     inlines = (AddressAdmin, )
     exclude = ('deleted', 'created_by')

     def created_at_readable(self, obj):
         return naturaltime(obj.created_at)

     created_at_readable.empty_value_display = "???"

请帮助我使用 Django Admin 添加 PhoneNumber

编辑:

我想将电话号码与每个地址相关联。所以在管理员电话号码字段将在地址模型中而不是在供应商中。谢谢

【问题讨论】:

【参考方案1】:

在网上冲浪后,我发现了这个名为 NestedAdmin 的库。该库支持 admin 中几乎所有类型的嵌套关系。我将在这里发布它的网址。

https://github.com/theatlantic/django-nested-admin

感谢您的宝贵时间。

【讨论】:

【参考方案2】:

在 VendorAdmin 中添加 PhoneNumber 的内联

 inlines = (AddressAdmin, PhoneNumberAdmin)

【讨论】:

这可行,但我希望 Address 模型中的 PhoneNumberAdmin 将多个号码与地址相关联,例如:Vendor->Address1->phone1-phone2 等。

以上是关于Django - 在管理面板中显示具有内容类型的模型的主要内容,如果未能解决你的问题,请参考以下文章

如何在从管理面板 Django 1.3 上传的模板中显示图像

我们如何在没有列表理解的情况下在 m2m 字段的 django 管理面板中显示用户

如何在 Django 中显示相对值?

Django:两种类型的用户同时登录

使用 sorl 的 django 管理面板中的缩略图

Django-Admin 面板不会显示插入的记录抛出 phpmyadmin?