如何在Django中为公共/抽象模型创建一个admin mixin



我正在创建一个多租户应用程序,并拥有以下抽象类,所有相关的租户特定模型都继承自:

class TenantAwareModel(models.Model):
tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE)
class Meta:
abstract = True

当在Django管理中注册模型时,我想保持我的代码DRY,而不必添加'tenant'到每个search_fields, list_display, list_filter等,所以我尝试创建一个超类来继承。

class TenantAwareAdmin(admin.ModelAdmin):
class Meta:
abstract = True
# change_form_template = "admin/professional_enquiry_change_form.html"
search_fields = ('tenant__id', 'tenant__name', 'tenant__domain',)
list_display = ('tenant',)
list_filter = ('tenant',)

然后尝试在其他模型的注册中继承它。例如

class UserAdmin(TenantAwareAdmin, admin.ModelAdmin ):
...

这种方法与tenanttawaremodel的工作方式相匹配。

class TenantAwareModel(models.Model):
tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE)
class Meta:
abstract = True
class User(AbstractUser, Uuidable, Timestampable, TenantAwareModel):
...

它当然给了我:

django.core.exceptions.ImproperlyConfigured: The model TenantAwareModel is abstract, so it cannot be registered with admin.

有谁知道避免重复代码的正确方法吗?

Meta类和abstract=True类只能在模型定义中定义,不能在ModelAdmin中定义。

TenantAwareModel是一个抽象模型,它允许您避免在其他模型的定义中重复公共字段,但是您不能在管理站点中注册抽象模型。抽象模型与任何表都没有关系,它的唯一任务是作为一个基,从这个基中继承其他表示表的模型(不是抽象模型),并且可以在管理站点中注册。

为了避免在search_fields, list_display等中重复相同的字段,您应该创建这样的mixin:

class TenantAwareAdminMixin:
search_fields = [..., ...]
list_display = [..., ...]
...

和继承

class UserAdmin(TenantAwareAdminMixin, admin.ModelAdmin):
...

但是有一个问题…如果你覆盖了TenantAwareAdminMixin中定义的一些字段,这将覆盖mixin提供的值,迫使你显式地将继承的值加上那些新值,就像这样:

class UserAdmin(TenantAwareAdminMixin, admin.ModelAdmin):
list_display = TenantAwareAdminMixin.list_display + ['new_value']
...

可以通过重写get_list_display等方法来获得类似的结果。

相关内容

  • 没有找到相关文章

最新更新