2011-04-26 42 views
22

所以我有一个模型,其中包括:访问类request.user基于通用视图CreateView的,以设置在Django FK场

class Place(models.Model): 
    .... 
    created_by = models.ForeignKey(User) 

我的观点是,像这样:

class PlaceFormView(CreateView): 
    form_class = PlaceForm 

    @method_decorator(login_required) 
    def dispatch(self, *args, **kwargs): 
     return super(PlaceFormView, self).dispatch(*args, **kwargs) 

是有没有办法让我访问request.user并将created_by设置为该用户?我浏览过文档,但似乎无法找到任何提示。

`

回答

22

如何重写form_valid这确实保存形式?自己保存,做任何你想做的事,然后做重定向。

class PlaceFormView(CreateView): 
    form_class = PlaceForm 

    @method_decorator(login_required) 
    def dispatch(self, *args, **kwargs): 
     return super(PlaceFormView, self).dispatch(*args, **kwargs) 

    def form_valid(self, form): 
     obj = form.save(commit=False) 
     obj.created_by = self.request.user 
     obj.save()   
     return http.HttpResponseRedirect(self.get_success_url()) 
+0

谢谢!这有效,除了重定向。我得到错误:“没有URL重定向到。提供一个url或在模型上定义一个get_absolute_url方法。”但是,我在模型上设置了get_absolute_url(),当我第一次获得该视图时(使用表单上的选择框创建),它正确重定向。试图找出现在。有任何想法吗? – Brian 2011-04-26 04:32:12

+1

是的,看起来get_absolute_url被从self.object中拉出 - 所以在你的代码中,在'form_valid'中设置'self.object = obj' – 2011-04-26 04:50:22

+0

再次感谢。得到它的工作。 – Brian 2011-04-26 05:15:54

2

一种替代的方式来做到这一点是通过在CreateView的覆盖get_initial()方法来传递用户,并修改保存方法在PlaceForm类保存用户:

class PlaceForm(forms.ModelForm): 
    ... 
    ... 
    ... 

    def __init__(self, *args, **kwargs): 
     self.created_by = kwargs['initial']['created_by'] 
     super(PlaceForm, self).__init__(*args, **kwargs) 

    def save(self, commit=True): 
     obj = super(PlaceForm, self).save(False) 
     obj.created_by = self.created_by 
     commit and obj.save() 
     return obj 

class PlaceFormView(CreateView): 
    ... 
    ... 
    form_class = PlaceForm 

    def get_initial(self): 
     self.initial.update({ 'created_by': self.request.user }) 
     return self.initial 

这保存逻辑的方式仍然封装在表单类中。

+0

如果用户在数据库中是必填字段,则不起作用 – AmiNadimi 2017-09-01 19:22:05

8

我知道这是旧的,但对于其他人有这样的问题:

还有一个更简单的方法 - 因为保存形式多次将始终使用相同的模型实例,你也可以这样做:

def form_valid(self, form): 
    obj = form.save(commit=False) 
    obj.created_by = self.request.user 
    return super(PlaceFormView, self).form_valid(form) 

通过这种方式,您可以获得超级调用的所有优势 - 只需添加这两行代码就可以轻松实现,而且您不必通过复制重定向逻辑来重复自己。

相关问题