简体   繁体   English

如何链接在表单中选择的 Django 外键与内联表单?

[英]How do I link a Django foreign key selected in a form with an inline form?

Introduction介绍

Hello.你好。 I am a self-taught novice python/Django coder working on my family business truck maintenance Django app, I have some of the basics of Django and python3 down.我是一名自学成才的 python/Django 编码员,从事我的家族企业卡车维护 Django 应用程序,我掌握了 Django 和 python3 的一些基础知识。 but other basics escape me as everything I am learning has been done for practicality sake and not built from the foundations of these languages.但是其他基础知识让我无法理解,因为我所学的一切都是为了实用而完成的,而不是建立在这些语言的基础之上。

I have the following types of models:我有以下类型的模型:

  • Truck - a single truck卡车- 一辆卡车
  • Service - a single instance of a repair/maintenance service for a single truck服务- 单个卡车的维修/维护服务的单个实例
  • Photo - a single picture from the photologue app照片- 来自photologue应用程序的单张照片
  • PhotoExtended - an add-on model one-to-one with Photo where it can be linked to a truck and/or a service. PhotoExtended - 与 Photo 一对一的附加 model 可以链接到卡车和/或服务。 A photo will ALWAYS be associated with a truck, but may or may not be associated with a service.照片将始终与卡车相关联,但可能会或可能不会与服务相关联。

relevant models.py:相关models.py:

class PhotoExtended(models.Model):

    # Link back to Photologue's Photo model.
    photo = models.OneToOneField(Photo, related_name='extended', on_delete=models.RESTRICT)
    truck = models.ForeignKey('Truck', on_delete=models.CASCADE, 
                        default = DEFAULT_TRUCK_ID, help_text="Truck in the picture.")
    service = models.ForeignKey('Service', on_delete=models.PROTECT,
                        null=True, blank=True, help_text="Service being performed or finished in the picture.")
    receipt = models.BooleanField(help_text="Is the picture for a receipt?", null=True, default=False)
    
    # Boilerplate code to make a prettier display in the admin interface.
    class Meta:
        verbose_name = u'Associated photo'
        verbose_name_plural = u'Associated photos'

    def __str__(self):
        return self.photo.title

The problem at hand手头的问题

In the admin form set up, I have a nice service form with an inline PhotoExtended form;在设置的管理表单中,我有一个带有内联 PhotoExtended 表单的漂亮服务表单; however, I have not figured out how to update the PhotoExtended truck foreign key with the value selected in the form.但是,我还没有弄清楚如何使用表单中选择的值更新 PhotoExtended 卡车外键。 A lot of the answers I found date back to earlier versions of Django, so updating them to the current specifications hasn't worked for me.我找到的很多答案都可以追溯到 Django 的早期版本,因此将它们更新为当前规范对我来说不起作用。

shortened admin.py:缩短的 admin.py:

from django.contrib import admin
from django.utils.translation import ugettext_lazy
from django.urls import reverse
from photologue.admin import PhotoAdmin as PhotoAdminDefault, PhotoAdminForm
from photologue.models import Photo
from .models import Truck, Service, PhotoExtended

class PhotoExtendedInline(admin.StackedInline):
    model = PhotoExtended
    max_num=4
    extra=0
    can_delete = True
class PhotoAdmin(PhotoAdminDefault):
    inlines = [PhotoExtendedInline, ]
    view_on_site=False

class ServiceAdmin(admin.ModelAdmin):
...
    inlines = [
        PhotoExtendedInline,
    ]
    date_hierarchy = 'service_date'
...

In short, I need a way to access the information that was entered in the parent form and use it to prepopulate the Truck foreign key in the inline form.简而言之,我需要一种方法来访问在父表单中输入的信息,并使用它来预填充内联表单中的卡车外键。 The Service foreign key gets linked automatically, but not the one for the Truck.服务外键自动链接,但不是卡车的外键。

I would be grateful for any and all help with my question.对于我的问题,我将不胜感激。 Thank you!谢谢!

I figured it out.我想到了。 Kind of.有点儿。 It only works for already saved forms.它仅适用于已保存的表单。

First, I had to add add a class to the ServiceAdmin form:首先,我必须在 ServiceAdmin 表单中添加一个 class:

    def get_form(self, request, obj=None, **kwargs):
        request._service_obj = obj
        return super(ServiceAdmin, self).get_form(request, obj, **kwargs)

Then, for the Inline form, I had to add a foreignkey form method:然后,对于内联表单,我必须添加一个外键表单方法:

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        formfield = super(PhotoExtendedInline_Service, self).formfield_for_foreignkey(db_field, request, **kwargs)
        if db_field.name == 'truck':
            if request._service_obj is not None:
                formfield.queryset = formfield.queryset.filter(service__exact = request._service_obj)
            else:
                formfield.queryset = formfield.queryset.none()
        return formfield

I hope this helps out future coders!我希望这对未来的编码员有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM