我正在尝试将一个 kwarg 从 CreateView 传递给 ModelForm,以便我可以根据相关 Parent 对象中的值动态调整字段。其他答案表明,通过在视图中覆盖get_form_kwargs并在表单中使用kwarg.pop捕获它来传递 kwarg 应该可以工作,但是当我尝试时我得到一个AttributeError: 'ChildForm' has no attribute 'get' 。将 kwarg 传递到视图上下文中是可行的,但不允许我访问表单实例中的值。
模型.py:
class Parent(models.Model):
name = models.CharField(max_length=255)
details = models.CharField(max_length=255)
detailstwo = models.CharField(max_length=255, null=True)
child_mod = models.BooleanField(default=False)
slug = models.SlugField()
creator = models.ForeignKey(User)
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.name)
super(Parent, self).save(*args, **kwargs)
def __str__(self):
return self.name
class Child(models.Model):
parent = models.ForeignKey(Parent)
parent_mod = models.CharField(max_length=255)
child_name = models.CharField(max_length=255)
def __unicode__(self):
return self.child_name
视图.py:
class ChildCreateView(CreateView):
model = Child
form_class = ChildForm
template_name = 'testapp/child_form.html'
def dispatch(self, *args, **kwargs):
return super(ChildCreateView, self).dispatch(*args, **kwargs)
def get_form_kwargs(self, **kwargs):
kwargs = super(ChildCreateView, self).get_form_kwargs()
parent = get_object_or_404(Parent, slug=self.kwargs['parent_slug'])
kwargs['parent'] = parent
return kwargs
def get_context_data(self, **kwargs):
context = super(ChildCreateView, self).get_context_data(**kwargs)
parent = get_object_or_404(Parent, slug=self.kwargs['parent_slug'])
context['parent'] = parent
return context
def form_valid(self, form):
child = form.save(commit=False)
parent_slug = form.data['parent_slug']
parent = get_object_or_404(Parent, slug=parent_slug)
child.parent = parent
return super(ChildCreateView, self).form_valid(form)
def get_success_url(self):
return reverse('testapp:parent_view', kwargs={'slug': self.object.parent.slug})
表格.py:
class ChildForm(forms.ModelForm):
class Meta:
model = Child
fields = ['parent', 'parent_mod', 'child_name']
def __init__(self, *args, **kwargs):
self.parent_object = kwargs.pop('parent')
assert isinstance(self.parent_object, Parent)
super(ChildForm, self).__init__(self, *args, **kwargs)
self.fields["parent_slug"] = forms.CharField(widget=forms.HiddenInput())
if not self.parent_object.child_mod:
del self.fields['parent_mod']
完整的追溯在这里:http ://dpaste.com/2QBMRJX