2011-04-26 11 views
22

así que tengo un modelo que incluye:Acceso request.user en clase genérica basada vista CreateView con el fin de establecer el campo FK en Django

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) 

Es ¿Hay alguna forma de que acceda a request.user y configure created_by a ese usuario? He revisado los documentos, pero parece que no puedo encontrar pistas sobre esto.

`

Respuesta

22

¿Qué tal anulando form_valid, que es el que salva la forma? Guárdelo usted mismo, haga lo que quiera, luego haga 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()) 
+0

Gracias! Esto funciona, a excepción de la redirección. Me aparece el error: "No hay una URL para redirigir a. O bien proporciona una URL o define un método get_absolute_url en el Modelo". Sin embargo, tengo un conjunto de get_absolute_url() en el modelo, y cuando primero obtuve esta vista funcionando (con created_by un cuadro de selección en el formulario) se redirigió correctamente. Tratando de resolver esto ahora. ¿Algunas ideas? – Brian

+1

Sí, parece que get_absolute_url se extrae de self.object, por lo que en su código, establezca 'self.object = obj' en' form_valid' –

+0

Gracias de nuevo. Lo tengo trabajando. – Brian

2

Una forma alternativa de hacer esto es pasar el usuario a través de sobrescribir el método get_initial() en la CreateView, y modificar ahorrar método en la clase PlaceForm para guardar el 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 

Este manera en que la lógica de ahorro aún está encapsulada dentro de la clase de formulario.

+0

no funciona si el usuario es un campo obligatorio en la base de datos – AmiNadimi

8

Yo sé que esto es viejo, pero para otras personas con este problema:

Hay una forma aún más simple - desde el ahorro de una forma varias veces, siempre utilizamos la misma instancia de modelo, también se 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, obtener todos los beneficios de la llamada súper - es trivial para ver que estás realmente sólo la adición de estas dos líneas de código, y usted no tiene que repetirse replicando la lógica de redireccionamiento .

Cuestiones relacionadas