假设尝试使用django.views.generic.create_update.create_object来允许用户访问博客条目实例。在Entry模型中,用户有一个必填字段,我不希望在博客条目表单中显示为可编辑字段。所以,我会将它包含在EntryForm.Meta.exclude元组中。
我应该在结果模型实例的哪个位置设置用户属性的值?我是否必须停止使用create_object通用视图并编写自己的视图?
答案 0 :(得分:2)
我认为你不能用通用视图来实现这一点,它们对后期处理数据没有多少帮助。值得庆幸的是,编写自己的视图并不难做同样的事情。
(改编自http://www.djangobook.com/en/1.0/chapter07/)
from yourmodel.forms import EntryForm
def create_entry(request):
if request.method == 'POST':
form = EntryForm(request.POST)
if form.is_valid():
entry = form.save(commit = false)
entry.author = request.user.username
entry.save()
return HttpResponseRedirect('/create_entry/thanks/')
else:
form = EntryForm()
return render_to_response('/path/to/template.html', {'form' : form, ...}, ...)
当然你必须使用自己的名字等,但这就是逻辑。基本上,您正在检查表单是否已提交,如果是,请获取条目,添加用户名,并照常保存。就通用create_object视图的差异而言,不是在视图调用中指定诸如post_redirect_url之类的东西,而是直接给出它们。查看render_to_response和HttpResponseRedirect的文档以获取更多信息。
答案 1 :(得分:1)
我只是要解决这个问题,并且不想作弊。这并不难。请查看以下内容。
请注意,只有这个错综复杂,因为我选择坚持我对MVC分离的看法。用户群是特定于视图的(因为我们在编辑中没有特殊的初始用户)。处理是特定于模型的。
提取一个需要新的“passthrough”参数的表单mixin并自动将排除与转发初始数据合并起来并不困难。这也增加了知道没有人可以在视图中修改这些字段数据的安全性。
class TestForm(forms.ModelForm):
class Meta:
exclude = ('user')
model = models.Test
def save(self, commit=True):
obj = super(CharmForm, self).save(commit=False)
obj.user = self.initial['user']
if commit:
obj.save()
class TestView(CreateView):
model = models.Test
form_class = TestForm
def get_initial(self,**kwargs):
initial = super(CreateView,self).get_initial()
c = RequestContext(self.request)
initial = initial.copy()
initial['user'] = c['user']
return initial
此外,还不完全确定您是否尝试使用新的基于类的视图。我实际上是在为这个问题的任何人回答这个问题(我不得不破解代码来找到答案,因为似乎没有其他人这样做过。)
答案 2 :(得分:0)
sykora的解决方案有一个小问题:如果表单无效,您将收到错误,因为表单不会被设置(在if语句的范围之外)。
这是一个稍好的版本:
from yourmodel.forms import EntryForm
def create_entry(request):
form = EntryForm()
if request.method == 'POST':
form = EntryForm(request.POST)
if form.is_valid():
entry = form.save(commit = false)
entry.author = request.user.username
entry.save()
return HttpResponseRedirect('/create_entry/thanks/')
return render_to_response('/path/to/template.html', {'form' : form, ...}, ...)