2012-03-02 12 views
7

In un UpdateView di classi in Django, escludo il campo utente in quanto è interno al sistema e non lo chiederò. Ora qual è il vero modo Django di far passare l'utente nella forma. (Come faccio ora, sto passando l'utente nello init del modulo e poi sovrascrivo il metodo save() del modulo. Ma scommetto che c'è un modo corretto di farlo. Qualcosa come un campo nascosto o . cose di questa naturavisualizzazione basata su classe Django - UpdateView - Come accedere all'utente della richiesta durante l'elaborazione di un modulo?

# models.py 
class Entry(models.Model): 
    user = models.ForeignKey(
       User, 
       related_name="%(class)s", 
       null=False 
    ) 

    name = models.CharField(
       blank=False, 
       max_length=58, 
    ) 

    is_active = models.BooleanField(default=False) 

    class Meta: 
     ordering = ['name',] 

    def __unicode__(self): 
     return u'%s' % self.name 

# forms.py 
class EntryForm(forms.ModelForm): 
    class Meta: 
     model = Entry 
     exclude = ('user',) 

# views.py 
class UpdateEntry(UpdateView): 
    model = Entry 
    form_class = EntryForm 
    template_name = "entry/entry_update.html" 
    success_url = reverse_lazy('entry_update') 

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

# urls.py 
url(r'^entry/edit/(?P<pk>\d+)/$', 
    UpdateEntry.as_view(), 
    name='entry_update' 
), 

risposta

7

hacking in giro come il superamento di un campo nascosto non ha senso in quanto questo ha davvero nulla a che fare con il cliente - questa "associato con l'utente connesso" classico problema dovrebbe assolutamente essere gestito su il lato server.

avevo messo questo comportamento nel metodo form_valid.

class MyUpdateView(UpdateView): 
    def form_valid(self, form): 
     instance = form.save(commit=False) 
     instance.user = self.request.user 
     super(MyUpdateView, self).save(form) 

    # the default implementation of form_valid is... 
    # def form_valid(self, form): 
    #  self.object = form.save() 
    #  return HttpResponseRedirect(self.get_success_url()) 
+3

consiglio rimuovendo le ultime due righe ('.save()' e 'return') e la loro sostituzione con' super (MyUpdateView, auto) .form_valid (form) '. Questo eseguirà semplicemente il form_valid() predefinito (identico alle tue ultime due righe) sull'istanza del modulo modificato, mantenendo il tuo codice in sincrono con eventuali modifiche future apportate al progetto da Django a questo metodo. – Bryson

+0

@Bryson, bello! Non l'ho mai fatto prima. Suppongo che non sia immediatamente intuitivo che l'istanza sia referenziata su form.instance e quindi la modifica influenzi di nuovo la chiamata future save(). –

+0

Qualcosa che ho perso: invece di usare solo 'instance =' credo che dovresti usare 'form.instance ='. Questo aggiungerà l'utente dall'oggetto request (assumendo che il tuo modulo sia stato creato con questo campo, altrimenti verrà visualizzato un errore come "Form has no attribute 'user'") all'istanza del modulo, che verrà quindi passata indietro attraverso ' super() '. Come è scritto scrivi ora, la forma modificata con i dati dell'utente viene salvata in una variabile chiamata 'instance' che non lascia mai la tua versione di' form_valid', quindi perché sei passato a 'super()' non viene mai salvato. Mi dispiace è diventato complicato. haha – Bryson

2

È necessario restituire un oggetto HttpResponse. Il seguente codice funziona:

class MyUpdateView(UpdateView): 
    def form_valid(self, form): 
     instance = form.save(commit=False) 
     instance.user = self.request.user 
     return super(MyUpdateView, self).form_valid(form) 
Problemi correlati