我有一种编辑表单样式,我曾经使用过这样一种方式:通过告诉表单它正在编辑一个实例,而不是生成一个新的pk,从而允许用户提交表单:
edit_form = PrivateProfileForm(data=request.POST, instance=profile)
有问题的应用程序有一个具有必需的、唯一字段的模型,该字段应为(url):
^{pr2}$在基于类的视图中,传递instance=article表单的几次尝试都失败了,尽管是静默的,最近的一次失败是尝试form.instance = article_in_question
查看帖子:
class ArticleUpdateView(UpdateView):
model = Article
form_class = EditArticleForm
template_name = 'index/edit_article.html'
def get_context_data(self, **kwargs):
context = super(ArticleUpdateView, self).get_context_data(**kwargs)
context['tags'] = Tag.objects.all()
return context
def add_tags(self, article, tags_to_add):
for tag in tags_to_add:
article.tags.add(tag)
def form_invalid(self, **kwargs):
return self.render_to_response(self.get_context_data(**kwargs))
def post(self, request, *args, **kwargs):
self.object = None
article_in_question = Article.objects.get(pk=self.kwargs['pk'])
print article_in_question
form_class = self.get_form_class()
form_name = 'form'
form = self.get_form(form_class)
if form.is_valid():
tags_chosen = request.POST.getlist('selected_tags')
form.instance = article_in_question
article = form.save(commit=False)
article.save()
self.add_tags(article, tags_chosen)
return self.form_valid(form)
else:
return self.form_invalid(**{form_name: form})
Tag和Article是独立的模型,所以我还没有找到一种方法将它们轻松地集成到一个表单中。在视图中添加标记很好,并且可以创建文章,所以我只想允许提交这个预先填充的表单,而不尝试创建新的模型(由于独特的需求而失败)。在
我当前编辑表单和原始表单进行比较:
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ('url', 'title', 'user')
url = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'required'}),
max_length=256, label='URL', required=True)
title = forms.CharField(widget=forms.TextInput(attrs={"placeholder": "I'll grab the page's title"}),
max_length=256, label='Title', required=False)
user = forms.CharField(widget=forms.HiddenInput())
def clean(self):
try:
title = self.cleaned_data['title']
url = self.cleaned_data['url']
title = process_title(url)
self.cleaned_data['title'] = title
except:
pass
username = self.cleaned_data['user']
user = User.objects.get(username=username)
self.cleaned_data['user'] = user
super(ArticleForm, self).clean()
return self.cleaned_data
class EditArticleForm(forms.ModelForm):
url = forms.CharField(required=False)
title = forms.CharField(required=False)
class Meta:
model = Article
fields = ('url', 'title')
我将表单称为与创建对象时相同的形式,并且在视图中,article_in_question
将作为真实的文章出现。如果您感兴趣,模板如下所示(与创建对象的表单相同):
<form id="article_form" method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form|bootstrap }}
{% for tag in tags %}
<div style="display:inline-block;" >
<input type="checkbox" name="selected_tags" id="option{{tag.id}}" value={{tag.name}} />
<label for="option{{tag.id}}">{{tag.name}}</label>
</div>
{% endfor %}
<br/>
<input type="submit" name="submit" value="Edit article"/>
在贝壳里看到:
In [5]: v = ArticleUpdateView()
In [8]: v.form_class
Out[8]: index.forms.EditArticleForm
In [14]: a = Article.objects.create(url='fake.com', title="fake")
In [15]: a
Out[15]: <Article: fake>
In [19]: form =v.form_class(instance=a)
In [20]: form
Out[20]: <EditArticleForm bound=False, valid=Unknown, fields=(url;title)>
我很惊讶:
form_class = self.get_form_class()
form_class.instance = article_in_question
print form_class.instance
form_name = 'form'
form = self.get_form(form_class)
没用。打印form_class.instance
表明适当的文章附加到了该表单类。在
如何告诉窗体它正在这些基于类的视图中的实例上工作?在
别担心。如果其他学习类视图的人Django想学习这个,请注意}的操作。解决办法是:
form = self.get_form(form_class)
正在内部执行一个覆盖instance
到{了解这些复杂的类视图的方法是进入ipython并获取一个类似的
^{pr2}$然后直接玩它的物品:
事实证明,这比读几个小时的文档要有效得多;虽然非常全面,但在许多情况下,它们似乎缺乏实际的例子
相关问题 更多 >
编程相关推荐