在使用通用视图创建模型实例时,如何设置模型实例的属性?

时间:2009-01-18 08:14:02

标签: django

假设尝试使用django.views.generic.create_update.create_object来允许用户访问博客条目实例。在Entry模型中,用户有一个必填字段,我不希望在博客条目表单中显示为可编辑字段。所以,我会将它包含在EntryForm.Meta.exclude元组中。

我应该在结果模型实例的哪个位置设置用户属性的值?我是否必须停止使用create_object通用视图并编写自己的视图?

3 个答案:

答案 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, ...}, ...)