我正在尝试将一个kwarg从CreateView传递给一个ModelForm,这样我就可以根据相关Parent对象中的值动态调整字段。其他答案表明,通过在视图中覆盖 get_form_kwargs 并在表单中使用 kwarg.pop 来传递kwarg应该可以正常工作,但我得到一个 AttributeError:我尝试时,'ChildForm'没有属性'get'。将kwarg传递给视图上下文可以正常工作,但是不允许我访问表单实例中的值。
models.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
views.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})
forms.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