Accessing request.user in class based generic view CreateView in order to set FK field in Django
So I have a m开发者_JS百科odel that includes:
class Place(models.Model):
....
created_by = models.ForeignKey(User)
My view is like so:
class PlaceFormView(CreateView):
form_class = PlaceForm
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(PlaceFormView, self).dispatch(*args, **kwargs)
Is there a way for me to access request.user and set created_by to that user? I've looked through the docs, but can't seem to find any hints toward this.
`
How about overriding form_valid
which does the form saving? Save it yourself, do whatever you want to it, then do the redirect.
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())
I know that this is old, but for other people with this problem:
There is an even simpler way - since saving a form multiple times will always use the same model instance, you can also do:
def form_valid(self, form):
obj = form.save(commit=False)
obj.created_by = self.request.user
return super(PlaceFormView, self).form_valid(form)
That way, you get all the benefits of the super call - it's trivial to see that you're really only adding those two lines of code, and you don't have to repeat yourself by replicating the redirect logic.
An alternate way to do this is to pass the user through overwriting the get_initial() method in the CreateView, and modify save method in the PlaceForm class to save the user:
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
This way the saving logic is still encapsulated within the form class.
精彩评论