簡體   English   中英

在 Django 管理員添加/更改表單中獲取外鍵數據

[英]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 查找以僅顯示屬於所選CustomerPet

# 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM