2010-03-13 14 views
20

I primi due paragrafi di questa pagina spiegano che viste generici sono tenuti a rendere la mia vita più facile, meno monotono, e mi renderà più attraente per le donne (ho fatto che l'ultimo):In inglese semplice, quali sono le viste generiche di Django?

https://docs.djangoproject.com/en/1.4/topics/generic-views/

I Sono tutto per migliorare la mia vita, ma cosa fanno effettivamente le viste generiche? Sembra che vengano lanciate molte parole d'ordine che confondono più di quanto spieghino.

Le viste generiche sono simili al ponteggio in Ruby on Rails? L'ultimo punto elenco nell'introduzione sembra indicare questo. È una dichiarazione accurata?

risposta

19

Le viste generiche di Django sono solo funzioni di visualizzazione (normali vecchie funzioni python) che fanno cose che sono molto comuni nelle applicazioni web.

A seconda del tipo di app che si sta creando, possono evitare di scrivere molte viste molto semplici.

Ad esempio, la vista generica direct_to_template visualizza semplicemente un modello con RequestContext (il che significa che il modello ha accesso alle informazioni sulla richiesta, come l'utente corrente, ecc.).

Come semplice esempio, si può andare da scrivere cose del genere:

# urls.py 
url('^some-url/$', some_view) 

# views.py 
def some_view(request): 
    return render_to_response('template_name.html', context_instance=RequestContext(request)) 

A proprio questo:

# urls.py 
url('^some-url/$', direct_to_template, {'template': 'template_name.html'}) 

# views.py doesn't need any code for this view anymore 

Ci sono anche più complicate vista generici per le azioni comuni come "mostrando un elenco di modelli "o" aggiunta di un modello al db ".

Inoltre, poiché le viste generiche sono solo funzioni, è possibile chiamarle all'interno delle proprie funzioni di visualizzazione per eseguire "la maggior parte del lavoro", quando è necessario qualcosa che sia leggermente diverso dai casi generici.

+2

Grazie, TM. Dovrebbero aggiungere questo alla documentazione :). Comunque non sono completamente venduto su viste generiche. Il tuo esempio che riguarda direct_to_template non salva molto codice (2 righe) e devi ancora specificare manualmente il modello. La parte peggiore è che rende la tua applicazione un po 'più difficile da capire, perché richiede che io conosca meglio Django di quanto sia necessario per fare questo semplice compito. – allyourcode

+1

@allyourcode Con le viste più complicate si sta per risparmiare molto più codice, ho scelto un esempio molto rapido. Inoltre, per quelle viste che operano su modelli, selezioneranno automaticamente un modello basato su una convenzione di denominazione (o può essere sovrascritto se non si desidera seguire la convenzione). Vedi http://docs.djangoproject.com/en/1.1/ref/generic-views/ per ulteriori esempi. Raccomando di scrivere alcune di queste viste da zero e quindi confrontarle. Nessuno di loro è enorme e complicato, è solo una cosa in meno da scrivere e fare il debug. –

+0

Grazie ancora, TM. Stavo già guardando i documenti per la versione di sviluppo di Django. – allyourcode

2

Per rispondere alla seconda domanda: no, le viste generiche non sono correlate allo scaffolding in RoR. L'impalcatura, come indica il nome, è simile alla generazione del codice. Le viste generiche sono qualcos'altro.

Il mio utilizzo principale della vista generica è una sostituzione di livello superiore delle funzioni base di render_to_response. Questo è come si potrebbe scrivere una vista semplice con render_to_response:

def my_view(request): 
    return render_to_response('my_template.html') 

Ma questo è molto semplice! Ad esempio il modello non avrà accesso al contesto della richiesta, a meno che non lo passi esplicitamente.

ho quindi preferisco usare una visione generica invece:

def my_view(request): 
    return direct_to_template(request, template='my_template.html') 

Ora il contesto di richiesta sarà trasmessa! E questo è solo un inizio. Le viste generiche sono utili quando si desidera visualizzare elenchi o viste di dettaglio, ad esempio. Gestiranno l'interrogazione del database e invieranno messaggi all'utente, tra l'altro.

Le viste generiche sono quindi funzioni di alto livello che consentono di creare una risposta da una vista.

+0

Le viste generiche potrebbero comportare la generazione di codice, ma sembrano svolgere un ruolo simile. In una versione precedente di Rails, era possibile dichiarare scaffolding in un controller (vista nel gergo di Django). Ciò darebbe dinamicamente al controller una serie di metodi che consentirebbero a un utente di eseguire operazioni CRUD di base sul modello corrispondente. – allyourcode

+0

Immagino tu intenda "le visualizzazioni generiche potrebbero ** non ** coinvolgere la generazione del codice, ma svolgono un ruolo simile". Direi piuttosto che la vista generica ... aiuta a creare una risposta da una vista, come ho detto. Una possibile applicazione è per le operazioni CRUD. Nota comunque che devi ancora scrivere il resto del codice, quindi non è sicuramente un'impalcatura. Inoltre, avrebbe senso scrivere le proprie viste generiche, se si ha ripetitività nelle creazioni di risposta. –

+0

+1 per menzionare come una visualizzazione generica può essere utilizzata nella tua funzione. Esp. chiamare la vista 'update_object' rende per me il meglio di entrambi i mondi: codice chiaro e ancora breve. – vdboor

4

Le visualizzazioni generiche consentono di scrivere codice molto più breve.

Confronta:

from django.http import HttpResponse, HttpResponseRedirect, Http404 
from django.shortcuts import render_to_response, get_object_or_404, redirect 
from myapp.models import Context 

def edit(request, item_id): 
    object = get_object_or_404(Context, pk=item_id) 

    if request.method == 'POST': 
     form = ContextForm(request.POST, instance=object) 
     if form.is_valid(): 
      form.save() 
      return redirect('myapp-context-index') 
    else: 
     form = ContextForm(instance=object) 

    return render_to_response("myapp/context/edit.html", {'object': object, 'form': form}) 

con:

from django.core import urlresolvers 
from django.views.generic.create_update import update_object 
from myapp.models import Context 

def edit(request, item_id):  
    return update_object(request, 
     object_id=item_id,    
     form_class=ContextForm,    
     template_name="myapp/context/edit.html", 
     post_save_redirect=urlresolvers.reverse("myapp-context-index") 
    ) 

come le vostre opinioni normali, sono funzioni normali. È possibile configurare completamente la vista in URLconf, se lo si desidera, grazie a questo aspetto mi sembra un po 'più chiaro.

come bonus, si ottiene anche:

  • Entra controlli di autenticazione (passa il login_required=True)
  • messaggio di stato successo da django.contrib.messages.
  • Meno codice per verificare la presenza di errori.
  • Un valore predefinito ModelForm quando si fornisce un parametro model anziché form_class.

Il template_name ha un valore predefinito "appname/model_form.html", ma è un po 'troppo per me.


Ecco la classe form entrambi condividono:

class ContextForm(forms.ModelForm): 
    """The form for a context""" 
    class Meta: 
     model = Context 
     exclude = ('collection',) 

    def save(self, commit=True): 
     """Overwritten save to force collection_id to a value""" 
     model = super(ContextForm, self).save(commit=False) 
     model.collection_id = 1 
     if commit: 
      model.save() 
     return model 
Problemi correlati