[英]Getting Foreign Key data in Django Admin Add/Change Form
我正在尝试为项目自定义 Django 管理员添加/更改。 我创建了一个名为“访问”的 model,其中包含 3 个外键字段:“客户”、“宠物”和“医生”。 工作流程如下:
下面是我的models.py
的代码
class Visit(models.Model):
customer = models.ForeignKey('customer.Customer', on_delete=models.CASCADE)
pet = models.ForeignKey('pet.Pet', on_delete=models.CASCADE)
date = models.DateTimeField()
doctor = models.ForeignKey(
'configuration.Doctor', on_delete=models.DO_NOTHING, null=True, blank=True)
status = models.CharField(
choices=PET_STATUS, max_length=3, null=True, blank=True)
reason = models.CharField(max_length=255)
diagnosis = models.TextField(null=True, blank=True)
treatment = models.TextField(null=True, blank=True)
comment = models.TextField(null=True, blank=True)
prescription = models.TextField(null=True, blank=True)
weight = models.DecimalField(
max_digits=6, decimal_places=2, null=True, blank=True)
class Meta:
ordering = ('-date',)
我的问题是使用 Django 管理员创建访问的人可能会错误地选择客户和宠物。 因此,客户不拥有该宠物。 我想知道如何自定义 Django 管理员,以便当用户选择客户时,选择框中仅显示该特定客户下的宠物。
下面是我的admin.py
class VisitAdmin(admin.ModelAdmin):
change_form_template = 'visit/invoice_button.html'
add_form_template = 'visit/add_visit.html'
list_display = ('customer', 'pet', 'date', 'status')
list_filter = ('date', 'customer', 'pet', 'status')
search_fields = ('customer__first_name',
'customer__last_name', 'pet__pet_name')
autocomplete_fields = ['customer', 'pet', 'doctor']
radio_fields = {'status': admin.HORIZONTAL}
fieldsets = (
(None, {
"fields": ('customer', 'pet', 'doctor'),
}),
("Visit Details", {
"fields": ('date', 'reason', 'weight', 'status'),
}),
("Visit Outcome", {
"fields": ('diagnosis', 'treatment', 'comment')
})
)
inlines = [FeeInLine, AttachmentInLine]
actions = ['export_as_csv']
def export_as_csv(self, request, queryset):
meta = self.model._meta
field_names = [field.name for field in meta.fields]
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename={}.csv'.format(
meta)
writer = csv.writer(response)
writer.writerow(field_names)
for obj in queryset:
row = writer.writerow([getattr(obj, field)
for field in field_names])
return response
export_as_csv.short_description = "Export Selected"
def response_change(self, request, obj):
if "invoice" in request.POST:
return render_pdf(request, obj.pk)
return super().response_change(request, obj)
admin.site.register(Visit, VisitAdmin)
我遇到了同样的问题,在我的情况下,我使用raw_id_field
作为我的外键和 ModelAdmin 中的多对多字段并覆盖添加和更改模板。
您可以将raw_id_field
用于外键,并在模板中编写 javascript 以在Customer
id 字段更改时更改Pet
外键字段的搜索图标的href
,并在href
中使用 url 查找以仅显示属于所选Customer
的Pet
# stock/models.py
class Category(models.Model):
title = models.CharField(max_length=255, blank=True)
is_active = models.BooleanField(default=True)
class Product(models.Model):
category = models.ForeignKey(
Category, on_delete=models.PROTECT, related_name="product"
)
feature_option = models.ManyToManyField("FeatureOption", blank=True, related_name="product")
class Feature(models.Model):
title = models.CharField(max_length=255, blank=True)
category = models.ManyToManyField(Category, blank=True, related_name="feature")
class FeatureOption(models.Model):
title = models.CharField(max_length=255, blank=True)
feature = models.ForeignKey(
Feature, on_delete=models.CASCADE, related_name="feature_option"
)
# stock/admin.py
class CategoryAdmin(admin.ModelAdmin):
raw_id_fields = ['parent']
class ProductAdmin(admin.ModelAdmin):
add_form_template = 'admin/product_add_form.html'
change_form_template = 'admin/product_change_form.html'
raw_id_fields = ['category', "feature_option"]
class FeatureOptionAdmin(admin.ModelAdmin):
list_filter = (("feature__category", admin.RelatedOnlyFieldListFilter),)
在我的模板中,我使用 javascript 更改 url 查找的FeatureOption
搜索图标的href
<!-- product_add_form.html -->
{% extends "admin/change_form.html" %}
{% load i18n %}
{% block admin_change_form_document_ready %} {{ block.super }}
<script lang="text/javascript">
function changeFeatureOptionPopupUrl() {
const featureOptionBaseUrl = "/admin/stock/featureoption/";
let categoryTextBox = document.getElementById("id_category");
document.getElementById("lookup_id_feature_option").href = featureOptionBaseUrl + "?feature__category__id__exact=" + categoryTextBox.value;
}
document.getElementById("lookup_id_feature_option").onfocus = function () {changeFeatureOptionPopupUrl()}
</script>
{% endblock %}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.