addChild() 缺少 1 个必需的位置参数:'pk

addChild() missing 1 required positional argument: 'pk

我有两个模型,即Parent和Child。我已经设法制作了一个用于注册 Parent 的模型表格。现在我希望能够将 child 添加到 parent.

预期结果:每个 parent 都应该有一个 link 来调出 child 注册表。 Parent 名称字段的初始值应为 parent。

我目前遇到这个错误,

addChild() 缺少 1 个必需的位置参数:'pk

models.py

class Parent(models.Model):
surname = models.CharField(max_length=150, null=False, blank=False)
first_name = models.CharField(max_length=150, null=False, blank=False)

class Child(models.Model):
parent = models.ForeignKey(Parent, null=True, blank=True, on_delete=SET_NULL)
first_name = models.CharField(max_length=50, null=False, blank=False)
last_name = models.CharField(max_length=50, null=False, blank=False)

views.py(我在 addChild 视图中遗漏了什么?)

def addParent(request):
form = ParentForm()

if request.method == 'POST':
    form = ParentForm(request.POST, request.FILES)
if form.is_valid():
    form.save()

def addChild(request, pk):
parent = Parent.objects.get(id=pk)
form = ChildForm(initial={'parent' :parent})

if request.method == 'POST':
    form = ChildForm(request.POST)
if form.is_valid():
    form.save()

pk URL 应该是 URL 的一部分,因此您需要将 urlpatterns 更新为:

path('add_child/<strong><int:pk></strong>/', views.addChild, name='add_child'),

如果你这样访问URL,你应该访问add_child/<b><i>123</i></b>/123 您要为其添加子项的父项的主键。

由于父级的主键在URL中,将其保留在表单中意义不大。您可以将 ChildForm 重写为:

from django import forms

class ChildForm(forms.ModelForm):
    class Meta:
        model = Child
        <strong>fields = ['first_name', 'last_name']</strong>  # ← no parent

并在提交表单时让视图设置父级:

from django.shortcuts import redirect

def addChild(request, pk):
    if request.method == 'POST':
        form = ChildForm(request.POST)
        if form.is_valid():
            form.instance<strong>.parent_id = pk</strong>
            form.save()
            return redirect('<em>name-of-some-view</em>')
    else:
        form = ChildForm(initial={'parent' :parent})
    # …

Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.


Note: Functions are normally written in snake_case, not PascalCase, therefore it is advisable to rename your function to add_child, not addChild.