Ricerca…


Osservazioni

Quando si usa CBV, spesso abbiamo bisogno di sapere esattamente quali metodi possiamo sovrascrivere per ogni classe generica. Questa pagina della documentazione di django elenca tutte le classi generiche con tutti i loro metodi appiattiti e gli attributi di classe che possiamo usare.

Inoltre, il sito Web Classy Class Based View fornisce le stesse informazioni con una bella interfaccia interattiva.

Viste basate sulla classe

Le visualizzazioni basate su classi ti consentono di concentrarti su ciò che rende le tue visualizzazioni speciali.

Una pagina statica sulla pagina potrebbe non avere nulla di speciale, tranne il modello usato. Usa un TemplateView ! Tutto quello che devi fare è impostare un nome per il modello. Lavoro fatto. Il prossimo.

views.py

from django.views.generic import TemplateView


class AboutView(TemplateView):
    template_name = "about.html"

urls.py

from django.conf.urls import url
from . import views

urlpatterns = [
    url('^about/', views.AboutView.as_view(), name='about'),
]

Si noti come non usiamo direttamente AboutView . Questo perché ci si aspetta un callable e questo è esattamente ciò che as_view() restituisce.

Dati contestuali

A volte, il tuo modello ha bisogno di un po 'più di informazioni. Ad esempio, vorremmo avere l'utente nell'intestazione della pagina, con un link al suo profilo accanto al link di disconnessione. In questi casi, utilizzare il metodo get_context_data .

views.py

class BookView(DetailView):
    template_name = "book.html"

    def get_context_data(self, **kwargs)
        """ get_context_data let you fill the template context """
        context = super(BookView, self).get_context_data(**kwargs)
        # Get Related publishers
        context['publishers'] = self.object.publishers.filter(is_active=True)
        return context

È necessario chiamare il metodo get_context_data sulla super classe e restituirà l'istanza di contesto predefinita. Qualsiasi elemento aggiunto a questo dizionario sarà disponibile per il modello.

book.html

<h3>Active publishers</h3>
<ul>
  {% for publisher in publishers %}
    <li>{{ publisher.name }}</li>
  {% endfor %}
</ul>

Elenco e dettagli

Le viste del modello vanno bene per la pagina statica e potresti usarle per tutto con get_context_data ma sarebbe a malapena migliore dell'uso della funzione come viste.

Inserisci ListView e DetailView

app / models.py

from django.db import models

class Pokemon(models.Model):
    name = models.CharField(max_length=24)
    species = models.CharField(max_length=48)
    slug = models.CharField(max_length=48)

app / views.py

from django.views.generic import ListView, DetailView
from .models import Pokemon


class PokedexView(ListView):
    """ Provide a list of Pokemon objects """
    model = Pokemon
    paginate_by = 25

class PokemonView(DetailView):
    model = Pokemon

Questo è tutto ciò che serve per generare una vista che elenchi tutti gli oggetti di un modello e le viste di un oggetto singolare. L'elenco è persino impaginato. Puoi fornire template_name se vuoi qualcosa di specifico. Per impostazione predefinita, viene generato dal nome del modello.

app / templates / app / pokemon_list.html

<!DOCTYPE html>
<title>Pokedex</title>
<ul>{% for pokemon in pokemon_list %}
    <li><a href="{% url "app:pokemon" pokemon.pk %}">{{ pokemon.name }}</a>
        &ndash; {{ pokemon.species }}
</ul>

Il contesto è popolato con l'elenco di oggetti sotto il nome due, object_list e una seconda build dal nome del modello, qui pokemon_list . Se hai impaginato la lista, devi occuparti anche del link precedente e successivo. L'oggetto Paginator può essere d'aiuto, è disponibile anche nei dati di contesto.

app / templates / app / pokemon_detail.html

<!DOCTYPE html>
<title>Pokemon {{ pokemon.name }}</title>
<h1>{{ pokemon.name }}</h1>
<h2>{{ pokemon.species }} </h2>

Come in precedenza, il contesto viene popolato con l'oggetto del modello sotto l' object nome e il pokemon , il secondo derivato dal nome del modello.

app / urls.py

from django.conf.urls import url
from . import views

app_name = 'app'
urlpatterns = [
    url(r'^pokemon/$', views.PokedexView.as_view(), name='pokedex'),
    url(r'^pokemon/(?P<pk>\d+)/$', views.PokemonView.as_view(), name='pokemon'),
]

In questo snippet, l'url per la vista dettagliata viene creato utilizzando la chiave primaria. È anche possibile usare una lumaca come argomento. Questo dà un URL più bello che è più facile da ricordare. Tuttavia richiede la presenza di un campo chiamato slug nel tuo modello.

url(r'^pokemon/(?P<slug>[A-Za-z0-9_-]+)/$', views.PokemonView.as_view(), name='pokemon'),

Se un campo chiamato slug non è presente, è possibile utilizzare la slug_field impostazione DetailView per puntare a un campo diverso.

Per l'impaginazione, utilizza una pagina per ottenere parametri o inserire una pagina direttamente nell'URL.

Creazione di forme e oggetti

Scrivere una vista per creare oggetti può essere piuttosto noioso. Devi visualizzare un modulo, devi convalidarlo, devi salvare l'oggetto o restituire il modulo con un errore. A meno che non si usi una delle viste di modifica generiche .

app / views.py

from django.core.urlresolvers import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .models import Pokemon


class PokemonCreate(CreateView):
    model = Pokemon
    fields = ['name', 'species']


class PokemonUpdate(UpdateView):
    model = Pokemon
    fields = ['name', 'species']


class PokemonDelete(DeleteView):
    model = Pokemon
    success_url = reverse_lazy('pokedex')

CreateView e UpdateView hanno due attributi, model e fields obbligatori. Per impostazione predefinita, entrambi utilizzano un nome di modello basato sul nome del modello con suffisso "_form". Puoi modificare solo il suffisso con l'attributo template_name_suffix. DeleteView mostra un messaggio di conferma prima di eliminare l'oggetto.

Sia UpdateView che DeleteView devono recuperare l'oggetto. Usano lo stesso metodo di DetailView , estraendo la variabile dall'URL e facendo corrispondere i campi dell'oggetto.

app / templates / app / pokemon_form.html (estratto)

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save" />
</form>

form contiene il modulo con tutti i campi necessari. Qui, verrà visualizzato con un paragrafo per ogni campo a causa di as_p .

app / templates / app / pokemon_confirm_delete.html (estratto)

<form action="" method="post">
    {% csrf_token %}
    <p>Are you sure you want to delete "{{ object }}"?</p>
    <input type="submit" value="Confirm" />
</form>

Il tag csrf_token è richiesto a causa della protezione di django contro la falsificazione delle richieste. L'azione attributo è lasciata vuota poiché l'url che visualizza il modulo è uguale a quello che gestisce la cancellazione / salvataggio.

Rimangono due problemi con il modello, se si utilizza lo stesso esempio con l'elenco e l'esempio di dettaglio. In primo luogo, creare e aggiornare si lamenterà di un URL di reindirizzamento mancante. Questo può essere risolto aggiungendo un get_absolute_url al modello pokemon. Il secondo problema è la conferma dell'eliminazione che non mostra informazioni significative. Per risolvere questo problema, la soluzione più semplice è aggiungere una rappresentazione di stringa.

app / models.py

from django.db import models
from django.urls import reverse
from django.utils.encoding import python_2_unicode_compatible


@python_2_unicode_compatible
class Pokemon(models.Model):
    name = models.CharField(max_length=24)
    species = models.CharField(max_length=48)

    def get_absolute_url(self):
        return reverse('app:pokemon', kwargs={'pk':self.pk})

    def __str__(self):
        return self.name

Il decoratore di classe si assicurerà che tutto funzioni correttamente sotto python 2.

Esempio minimo

views.py :

from django.http import HttpResponse
from django.views.generic import View

class MyView(View):
    def get(self, request):
        # <view logic>
        return HttpResponse('result')

urls.py :

from django.conf.urls import url
from myapp.views import MyView

urlpatterns = [
    url(r'^about/$', MyView.as_view()),
]

Ulteriori informazioni sulla documentazione di Django »

Viste basate sulla classe Django: esempio di CreateView

Con le viste generiche basate sulla classe, è molto semplice e facile creare le viste CRUD dai nostri modelli. Spesso, l'amministratore di Django integrato non è abbastanza o non è preferito e abbiamo bisogno di lanciare le nostre visualizzazioni CRUD. I CBV possono essere molto utili in questi casi.

La classe CreateView bisogno di 3 cose: un modello, i campi da usare e l'url di successo.

Esempio:

from django.views.generic import CreateView 
from .models import Campaign

class CampaignCreateView(CreateView):
    model = Campaign
    fields = ('title', 'description')
    
    success_url = "/campaigns/list"

Una volta che il successo della creazione, l'utente viene reindirizzato a success_url . Possiamo anche definire un metodo get_success_url e utilizzare reverse o reverse_lazy per ottenere l'URL di successo.

Ora, dobbiamo creare un modello per questa vista. Il modello deve essere denominato nel formato <app name>/<model name>_form.html . Il nome del modello deve essere in maiuscolo. Ad esempio, se il mio nome dell'app è dashboard , per la vista create sopra devo creare un modello denominato dashboard/campaign_form.html .

Nel modello, una variabile form contiene il modulo. Ecco un codice di esempio per il modello:

<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save" />
</form>            

Ora è il momento di aggiungere la vista ai nostri modelli di URL.

url('^campaign/new/$', CampaignCreateView.as_view(), name='campaign_new'),

Se visitiamo l'URL, dovremmo vedere un modulo con i campi che abbiamo scelto. Quando inviamo, cercherà di creare una nuova istanza del modello con i dati e salvarla. In caso di successo, l'utente verrà reindirizzato all'URL di successo. In caso di errori, il modulo verrà visualizzato di nuovo con i messaggi di errore.

Una vista, più moduli

Ecco un rapido esempio di utilizzo di più moduli in una vista Django.

from django.contrib import messages
from django.views.generic import TemplateView

from .forms import AddPostForm, AddCommentForm
from .models import Comment

class AddCommentView(TemplateView):

    post_form_class = AddPostForm
    comment_form_class = AddCommentForm
    template_name = 'blog/post.html'

    def post(self, request):
        post_data = request.POST or None
        post_form = self.post_form_class(post_data, prefix='post')
        comment_form = self.comment_form_class(post_data, prefix='comment')

        context = self.get_context_data(post_form=post_form,
                                        comment_form=comment_form)

        if post_form.is_valid():
            self.form_save(post_form)
        if comment_form.is_valid():
            self.form_save(comment_form)

        return self.render_to_response(context)     

    def form_save(self, form):
        obj = form.save()
        messages.success(self.request, "{} saved successfully".format(obj))
        return obj

    def get(self, request, *args, **kwargs):
        return self.post(request, *args, **kwargs)


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow