based - Accediendo request.user en la vista genérica basada en la clase CreateView para establecer el campo FK en Django
django views (3)
Así que tengo un modelo que incluye:
class Place(models.Model):
....
created_by = models.ForeignKey(User)
Mi punto de vista es así:
class PlaceFormView(CreateView):
form_class = PlaceForm
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(PlaceFormView, self).dispatch(*args, **kwargs)
¿Hay alguna forma de acceder a request.user y configurar created_by a ese usuario? He revisado los documentos, pero parece que no puedo encontrar ningún indicio sobre esto.
`
¿Qué hay de anular form_valid
que form_valid
el formulario? Guárdalo tú mismo, haz lo que quieras, luego haz la redirección.
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())
Sé que esto es viejo, pero para otras personas con este problema:
Existe una forma aún más simple: dado que guardar un formulario varias veces siempre usará la misma instancia del modelo, también puede hacer:
def form_valid(self, form):
obj = form.save(commit=False)
obj.created_by = self.request.user
return super(PlaceFormView, self).form_valid(form)
De esa manera, obtiene todos los beneficios de la súper llamada; es trivial ver que en realidad solo está agregando esas dos líneas de código, y no tiene que repetirse replicando la lógica de redireccionamiento.
Una forma alternativa de hacer esto es pasar al usuario sobrescribiendo el método get_initial () en CreateView, y modificar el método de guardar en la clase PlaceForm para guardar al usuario:
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
De esta manera, la lógica de guardado todavía está encapsulada dentro de la clase de formulario.