[英]How can dependencies be injected into Django classes from one app into another?
Is there a clean method to inject dependencies from one Django app into another?是否有一种干净的方法可以将一个 Django 应用程序的依赖项注入另一个应用程序?
I have multiple Django apps with one of them being a base app.我有多个 Django 应用程序,其中一个是基础应用程序。 This means, that the other apps depend on it,but the base app should not be aware of the other apps.这意味着,其他应用程序依赖于它,但基础应用程序不应该知道其他应用程序。 In most cases this is not a problem with the dependents using ForeignKeys and ManyToMany relations to the models of the base app.在大多数情况下,对于使用 ForeignKeys 和 ManyToMany 关系到基本应用程序模型的依赖项来说,这不是问题。 However, when building the admin classes, in order to add inlines and links to the respective dependent class,it is necessary to specify this in the base app.但是,在构建管理类时,为了向各自依赖的 class 添加内联和链接,有必要在基础应用程序中指定这一点。 Is it possible to inject it directly from the dependent app?是否可以直接从依赖的应用程序注入它?
In addition to the answer for adding inlines , I had to add attributes to the class for the list disply and list filter.除了添加 inlines的答案之外,我还必须为列表显示和列表过滤器向 class 添加属性。 Below is the code to add this for one ForeignKey linked model.下面是为链接 model 的一个 ForeignKey 添加此代码的代码。 Foo is a parent model (in the sense of composition over inheritance ) to which several other child models link to via OneToOne or ForeignKey fields from other apps. Foo 是父 model (在 inheritance 的组合意义上),其他几个子模型通过 OneToOne 或其他应用程序的 ForeignKey 字段链接到该父级。 This ensures that the parent model and thereby the app in which it resides does not have any dependencies on its child models.这确保了父 model 以及它所在的应用程序对其子模型没有任何依赖关系。
Models and admin classes defined in the parent App A.在父 App A 中定义的模型和管理类。
# app_a/models.py
from django.db import models
class Foo(models.Model):
name = models.CharField(max_length=64)
# app_a/admin.py
from django.contrib import admin
from .models import Foo
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ["name"]
list_display_links = ("name",)
list_filter = []
list_select_related = []
Models and admin classes defined in the child App B.子 App B 中定义的模型和管理类。
# app_b/models.py
from django.db import models
from app_a.models import Foo
class BarComponent(models.Model):
foo = models.OneToOneField(
Foo,
primary_key=True,
related_name="bar_component",
on_delete=models.CASCADE,
)
bar_type = models.CharField(max_length=42)
# app_b/admin.py
from django.contrib import admin
from django.core.exceptions import ObjectDoesNotExist
from .models import BarComponent
from app_a.admin import FooAdmin
@admin.register(BarComponent)
class BarAdmin(admin.ModelAdmin):
pass
# Inject BarComponent aspect into admin for Foo
@mark_safe
def has_bar(self, obj):
try:
return '<a href="%s">%s</a>' % (
reverse(
"admin:appb_barcomponent_change",
args=(obj.bar_component.pk,),
),
obj.bar_component.bar_type,
)
except ObjectDoesNotExist:
return "-"
setattr(FooAdmin, "has_bar", has_bar)
setattr(FooAdmin.has_bar, "allow_tags", True)
setattr(FooAdmin.has_bar, "short_description", "Bar")
FooAdmin.list_display.append("has_bar")
FooAdmin.list_filter.append(("bar_component", admin.EmptyFieldListFilter))
FooAdmin.list_select_related.append("bar_component")
Disclaimer: The code was foobar'ed from functional code in my project.免责声明:代码是从我项目中的功能代码中删除的。 Therefore, it has not been tested, but the structure works my project .因此,它尚未经过测试,但该结构适用于我的项目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.