如何在 Django 表单中使用外键自动填充变量?

Posted

技术标签:

【中文标题】如何在 Django 表单中使用外键自动填充变量?【英文标题】:How to autofill variable with foreign key in django form? 【发布时间】:2019-02-03 02:38:44 【问题描述】:

简而言之:我想自动填充表单的外部变量:

TL;DR 这是项目link。 我有一个模型:

from django.db import models
from django.urls import reverse
# Create your models here.

class School(models.Model):
    name = models.CharField(max_length=256)
    principal = models.CharField(max_length=256)
    location = models.CharField(max_length=256)

    def __str__(self): return self.name

    def get_absolute_url(self):
        return reverse('basic:detail', kwargs='pk': self.pk)

class Student(models.Model):
    name = models.CharField(max_length=256)
    age = models.PositiveIntegerField()
    school = models.ForeignKey(School, on_delete=models.CASCADE, related_name='students')

    def __str__(self): return self.name

    def get_absolute_url(self):
        return reverse('basic:detail', kwargs='pk': self.school.pk)

和url.py:

urlpatterns = [
    path('', views.Index.as_view(), name='index'),
    path('list/', views.SchoolListView.as_view(), name='list'),
    path('<int:pk>/', views.SchoolDetailView.as_view(), name='detail'),
    path('create/', views.SchoolCreateView.as_view(), name='create'),
    path('update/<int:pk>/', views.SchoolUpdateView.as_view(), name='update'),
    path('delete/<int:pk>/', views.SchoolDeleteView.as_view(), name='delete'),

    path('student/create/', views.StudentCreateView.as_view(), name='creates'),
    path('student/create/<int:pk>', views.StudentCreateView.as_view(), name='createspk'),
    path('student/update/<int:pk>/', views.StudentUpdateView.as_view(), name='updates'),
    path('student/delete/<int:pk>/', views.StudentDeleteView.as_view(), name='deletes'),


]

我正在使用 CBV:

class StudentCreateView(CreateView):
    try:
        print("*******")
        print(pk)
    except:
        pass
    model = Student
    fields = ["name", "age", 'school']

我添加了一个在学校详细信息中创建学生的链接,如下所示:

当我点击用 pk 新建时,我正在传递学校的 pk,然后我去:

如您所见,学校字段是下拉菜单,没有选择任何内容,我想将学校默认值设置为调用它的学校,在本例中为 xavier school for gifted childrens .

我的创建学生代码是:

% extends "basic/base.html" %

% block content %
<h1>
    % if not form.instance.pk %
    Create Student:
    % else %
    Update Student:
    % endif %
</h1>
<form method="post">
    % csrf_token %
     form.as_p 
    <input type="submit" value="Submit" class="btn btn-primary">
</form>
% endblock content %

我该怎么做?提前致谢。

【问题讨论】:

这可以在表单的__init__ 函数中完成。你能发布你的表单代码吗? 我没有使用。因为它是基于类的视图。它正在隐式生成。 对不起,我错过了。我认为将get_initial() 方法添加到您的视图中就足够了。让我一起写一个答案。 【参考方案1】:

尝试像这样修改您的视图:

class StudentCreateView(CreateView):
    try:
        print("*******")
        print(pk)
    except:
        pass
    model = Student
    fields = ["name", "age", 'school']

    def get_initial(self):
        initial = super(StudentCreateView, self).get_initial()
        initial['school'] = School.objects.get(pk=self.kwargs['pk'])
        return initial

我还建议将 url 中的参数(然后在 get_initial 方法中)重命名为 school_pk 之类的名称,以明确您不要传递 pk 以使 Student 成为已创建。

【讨论】:

谢谢伙计。它就像一个魅力。 get_initial 对我来说是新的。为什么我无法在 try 块中获得 pk 的另一件事。我怎样才能得到那个外部函数? 你不能:你的 try 块在 Python 编译器读取代码时执行,而不是在运行时实例化类时执行。如果你想在调用视图时对 pk 做一些事情,你应该使用def dispatch(self, request, *args, **kwargs):方法。 docs.djangoproject.com/en/2.1/ref/class-based-views/base/… 别忘了调用super() 方法,否则会破坏你的视野。 另外:pk 不能直接访问,而是通过self.kwargs['pk'] 知道了。再次感谢您的帮助。 我收到 KeyError, 'pk'

以上是关于如何在 Django 表单中使用外键自动填充变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中向 ModelForm 添加外键字段?

为 Django 模型自动填充外键

django:如何从包含外键的多个模型中制作一个表单

如何自动填充表单框值填充另一个?

如何在 Django 中创建用于编辑的填充表单

如何在表 Spring + Hibernate + Spring Security 中填充外键