如何在 Django Admin 中显示关系
How to show relationship in Django Admin
我正在使用 Django 2.1,但我很难弄清楚如何在 Admin 上显示关系。
我有两个模型医院和单位,第三个是考试。他们是这样设置的,医院可以有很多单位,一个单位属于一个医院。考试模型具有考试名称和医院名称等考试属性。
class Hospital(models.Model):
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.name
class Unit(models.Model):
unit_name = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
parent_company = models.ForeignKey(
Hospital, related_name='unit_parent', on_delete=models.CASCADE, verbose_name="Hospital")
class Exam(models.Model):
unit_name = models.ForeignKey(
Hospital, related_name='hospital_pk', on_delete=models.CASCADE)
exam_name = models.CharField(max_length=255, blank=True,
null=True, verbose_name="Exam's name")
date = models.DateField()
time = models.TimeField()
def __str__(self):
return self.exam_name
class CustomExamAdmin(admin.ModelAdmin):
model = Exam
list_display = ('exam_name', 'time', 'alert',
'document', 'notes', 'report', 'patients_name', 'unit_name')
list_filter = ('exam_name', 'time')
list_select_related = ('unit_name',)
fieldsets = (
("Hospital's Name:", {
'fields': ('unit_name',)}),
('Types of Exams:', {
'fields': ('exam_name', 'modality', 'model_used')}),
("Patient's name:", {
'fields': ('patients_name',)}),
)
因此,在管理员的检查页面中,我可以 select 医院名称,但是我无法 select 医院所属的单位。我需要 select 医院及其所属单位。
我应该向 Exams 添加另一个外键,如下所示:
unit_selected = models.ForeignKey(
单位,related_name='unit_pk',on_delete=models.CASCADE)
例如:医院:Brookdale University Hospital
单位:市区单位
我得到的:
enter image description here
为了selectAdmin
中的Unit
,需要先将其添加到Exam
模型中。您有一个名为 unit_name
的字段,但您已将其定义为 Hospital
模型而非 Unit
模型的外键。如果您有一个 unit_name
字段,您实际上并不需要一个单独的 hospital
字段,因为您可以轻松地从 unit_name.parent_company
中获取它。所以你可以这样做:
class Exam(models.Model):
unit_name = models.ForeignKey(
Unit, related_name='exams', on_delete=models.CASCADE)
exam_name = models.CharField(max_length=255, blank=True,
null=True, verbose_name="Exam's name")
date = models.DateField()
time = models.TimeField()
def __str__(self):
return self.exam_name
对于管理员而言,我认为最简单的方法是在 select 时将医院名称作为单位名称的一部分,而不是 select 分开医院和单位它在管理员中,例如 Brookdale University Hospital|Downtown Unit
。这样你只需要一个下拉字段。你可以这样做:
from django import forms
class UnitChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return "{}|{}".format(obj.parent_company.name, obj.unit_name)
class CustomExamAdmin(admin.ModelAdmin):
model = Exam
list_display = ('exam_name', 'time', 'alert',
'document', 'notes', 'report', 'patients_name', 'get_hospital', 'unit_name')
list_filter = ('exam_name', 'time')
list_select_related = ('unit_name__parent_company',)
fieldsets = (
("Hospital's Name:", {
'fields': ('unit_name',)}),
('Types of Exams:', {
'fields': ('exam_name', 'modality', 'model_used')}),
("Patient's name:", {
'fields': ('patients_name',)}),
)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'unit_name':
return UnitChoiceField(
queryset=Unit.objects.all().select_related('parent_company').order_by(
'parent_company.name', 'unit_name'))
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def get_hospital(self, obj):
# required to add hospital name to list_display
return obj.unit_name.parent_company.name
get_hospital.short_description = 'Hospital'
另一个注意事项:ForeignKeyField
中的 related_name
是从外部模型返回到您正在定义的模型的关系。所以在 Unit
模型中
parent_company = models.ForeignKey(
Hospital, related_name='unit_parent', on_delete=models.CASCADE, verbose_name="Hospital")
应该是
parent_company = models.ForeignKey(
Hospital, related_name='units', on_delete=models.CASCADE, verbose_name="Hospital")
然后从 Hospital
模型中,您可以将单位列表称为 units
。
我正在使用 Django 2.1,但我很难弄清楚如何在 Admin 上显示关系。 我有两个模型医院和单位,第三个是考试。他们是这样设置的,医院可以有很多单位,一个单位属于一个医院。考试模型具有考试名称和医院名称等考试属性。
class Hospital(models.Model):
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.name
class Unit(models.Model):
unit_name = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
parent_company = models.ForeignKey(
Hospital, related_name='unit_parent', on_delete=models.CASCADE, verbose_name="Hospital")
class Exam(models.Model):
unit_name = models.ForeignKey(
Hospital, related_name='hospital_pk', on_delete=models.CASCADE)
exam_name = models.CharField(max_length=255, blank=True,
null=True, verbose_name="Exam's name")
date = models.DateField()
time = models.TimeField()
def __str__(self):
return self.exam_name
class CustomExamAdmin(admin.ModelAdmin):
model = Exam
list_display = ('exam_name', 'time', 'alert',
'document', 'notes', 'report', 'patients_name', 'unit_name')
list_filter = ('exam_name', 'time')
list_select_related = ('unit_name',)
fieldsets = (
("Hospital's Name:", {
'fields': ('unit_name',)}),
('Types of Exams:', {
'fields': ('exam_name', 'modality', 'model_used')}),
("Patient's name:", {
'fields': ('patients_name',)}),
)
因此,在管理员的检查页面中,我可以 select 医院名称,但是我无法 select 医院所属的单位。我需要 select 医院及其所属单位。 我应该向 Exams 添加另一个外键,如下所示: unit_selected = models.ForeignKey( 单位,related_name='unit_pk',on_delete=models.CASCADE)
例如:医院:Brookdale University Hospital 单位:市区单位
我得到的: enter image description here
为了selectAdmin
中的Unit
,需要先将其添加到Exam
模型中。您有一个名为 unit_name
的字段,但您已将其定义为 Hospital
模型而非 Unit
模型的外键。如果您有一个 unit_name
字段,您实际上并不需要一个单独的 hospital
字段,因为您可以轻松地从 unit_name.parent_company
中获取它。所以你可以这样做:
class Exam(models.Model):
unit_name = models.ForeignKey(
Unit, related_name='exams', on_delete=models.CASCADE)
exam_name = models.CharField(max_length=255, blank=True,
null=True, verbose_name="Exam's name")
date = models.DateField()
time = models.TimeField()
def __str__(self):
return self.exam_name
对于管理员而言,我认为最简单的方法是在 select 时将医院名称作为单位名称的一部分,而不是 select 分开医院和单位它在管理员中,例如 Brookdale University Hospital|Downtown Unit
。这样你只需要一个下拉字段。你可以这样做:
from django import forms
class UnitChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return "{}|{}".format(obj.parent_company.name, obj.unit_name)
class CustomExamAdmin(admin.ModelAdmin):
model = Exam
list_display = ('exam_name', 'time', 'alert',
'document', 'notes', 'report', 'patients_name', 'get_hospital', 'unit_name')
list_filter = ('exam_name', 'time')
list_select_related = ('unit_name__parent_company',)
fieldsets = (
("Hospital's Name:", {
'fields': ('unit_name',)}),
('Types of Exams:', {
'fields': ('exam_name', 'modality', 'model_used')}),
("Patient's name:", {
'fields': ('patients_name',)}),
)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'unit_name':
return UnitChoiceField(
queryset=Unit.objects.all().select_related('parent_company').order_by(
'parent_company.name', 'unit_name'))
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def get_hospital(self, obj):
# required to add hospital name to list_display
return obj.unit_name.parent_company.name
get_hospital.short_description = 'Hospital'
另一个注意事项:ForeignKeyField
中的 related_name
是从外部模型返回到您正在定义的模型的关系。所以在 Unit
模型中
parent_company = models.ForeignKey(
Hospital, related_name='unit_parent', on_delete=models.CASCADE, verbose_name="Hospital")
应该是
parent_company = models.ForeignKey(
Hospital, related_name='units', on_delete=models.CASCADE, verbose_name="Hospital")
然后从 Hospital
模型中,您可以将单位列表称为 units
。