我正在构建一个常见问题解答应用程序。
模型流程主题->章节->文章。
Article有一个到Section的FK, Section有一个到Topic的FK。
在我的创建文章中,我想要在Topic_Pk中,所以当用户选择一个Section时,选择的选择仅限于Topic下附加的Sections。
我使用get_from_kwarg将Topic_Pk从url传递到表单中的__init__
。我一直得到一个TypeError __init__() got an unexpected keyword argument 'topic_pk'
。我不想在__init__
参数中弹出数据或设置topic_pk=None,因为这会使整个点无效。
我缺少什么来允许我使用这个变量?
Url:url(r'^ironfaq/(?P<topic_pk>d+)/article/create$', ArticleCreateView.as_view()),
视图:
class ArticleCreateView(CreateView):
model = Article
form_class = CreateArticleForm
template_name = "faq/form_create.html"
success_url = "/ironfaq"
def get_form_kwargs(self):
kwargs = super(ArticleCreateView,self).get_form_kwargs()
kwargs.update(self.kwargs)
return kwargs
形式:
class CreateArticleForm(forms.ModelForm):
section = forms.ModelChoiceField(queryset=Section.objects.none())
def __init__(self, *args, **kwargs):
super(CreateArticleForm, self).__init__(*args, **kwargs)
self.fields['section'].queryset = Section.objects.filter(topic_pk=self.kwargs['topic_pk'])
class Meta:
model = Article
widgets = {
'answer': forms.Textarea(attrs={'data-provide': 'markdown', 'data-iconlibrary': 'fa'}),
}
fields = ('title','section','answer')
模型:
class Article(Audit):
title = models.CharField(max_length=255)
sort = models.SmallIntegerField()
slug = models.SlugField()
section = models.ForeignKey(Section,on_delete=models.CASCADE)
answer = models.TextField()
vote_up = models.IntegerField()
vote_down = models.IntegerField()
view_count = models.IntegerField(default=0)
class Meta:
verbose_name_plural = "articles"
def __str__(self):
return self.title
def total_votes(self):
return self.vote_up + self.vote_down
def percent_yes(self):
return (float(self.vote_up) / self.total_votes()) * 100
def get_absolute_url(self):
return ('faq-article-detail',(), {'topic__slug': self.section.topic.slug,
'section__slug': self.section.slug, 'slug': self.slug})
对于当前的__init__
签名,在调用super()
之前,必须从kwargs中弹出topic_pk
,否则您将获得TypeError
。
在你的问题中,你说弹出值会"使整个点无效",但我认为你错了。调用super()
后,仍然可以使用topic_pk
的值。
class CreateArticleForm(forms.ModelForm):
section = forms.ModelChoiceField(queryset=Section.objects.none())
def __init__(self, *args, **kwargs):
topic_pk = kwargs.pop('topic_pk')
super(CreateArticleForm, self).__init__(*args, **kwargs)
self.fields['section'].queryset = Section.objects.filter(topic_pk=topic_pk)
另一种方法是使用topic_pk
作为命名参数。注意,这会改变__init__
方法的签名,因此它可能会破坏其他代码(例如,如果您在其他地方有CreateArticleForm(request.POST)
)。
def __init__(self, topic_pk=None, *args, **kwargs):
super(CreateArticleForm, self).__init__(*args, **kwargs)
self.fields['section'].queryset = Section.objects.filter(topic_pk=topic_pk)