web-dev-qa-db-fra.com

Comment utiliser CreateView avec un ModelForm

Je reçois une erreur dans ma classe AuthorCreateForm lorsque je soumets mon formulaire. NameError self n'est pas défini

Comment utiliser un CreateForm?

J'ai créé une classe dans mon fichier Author.py

from Django.views.generic import TemplateView, ListView, CreateView
from books.models import Author, Publisher, Book
from books.forms import AuthorForm

class AuthorCreateView(CreateView):
    objAuthorForm = AuthorForm(self.request.POST)

    if(objAuthorForm.save()):
        success = "Form saved!"
    else:
        error = "There was an error!"

et j'ai un modèle html qui se soumet à/Author/Create

et j'ai la ligne suivante dans mon urls.py

('^authors/create/$', Author.AuthorCreateView.as_view()),

Je rend le formulaire à cette URL

('^authors/new/$', TemplateView.as_view(template_name="author_new.html")),

Je trouve les vues basées sur la classe déroutantes, est-ce que quelqu'un a un bon tutoriel sur la façon de l'utiliser pour les opérations CRUD?

Merci

51
iJK

Ce que vous avez est une erreur python - self n'est pas définie. self est généralement ce qui fait référence à l'instance de classe elle-même sur les méthodes de classe.

Quoi qu'il en soit, je suis d'accord, c'est flambant neuf et pas comme documenté. Je pense que regarder la source est absolument essentiel à ce stade.

Pour être à l'aise avec les vues basées sur une classe, je commencerais par sous-classer Django.views.generic.base.View, Qui n'implémente que quelques méthodes, à savoir tenter d'appeler une fonction sur la classe en fonction de la méthode request (post, get, head, - regardez à la source).

Par exemple, voici la première étape pour remplacer les fonctions d'affichage par les nouvelles classes d'affichage:

class MyClassBasedView(View):
    def get(self, request):
        # behave exactly like old style views
        # except this is called only on get request
        return http.HttpResponse("Get")

    def post(self, request):
        return http.HttpResponse("Post")

(r'^foobar/$', MyClassBasedView.as_view())

Retour à votre question spécifique:

Tout ce que TemplateView.as_view() fait est de rendre le modèle - CreateView est une combinaison de plusieurs autres classes qui gèrent ModelForms et le rendu de modèle (TemplateView).

Donc, pour un exemple très basique, regardez la documentation pour quelle classe mixins sont utilisées par CreateView.

Nous voyons qu'il implémente TemplateResponseMixin, ModelFormMixin et ProcessFormView, chacun contenant une liste de méthodes pour ces classes.


Le CreateView le plus basique

Au niveau le plus basique, fournissez à CreateViewModelFormMixin avec le modèle ou la classe ModelForm personnalisée comme indiqué ici.

Votre classe CreateView ressemblerait à ceci:

class AuthorCreateView(CreateView):
    form_class = AuthorForm
    template_name = 'author_new.html'
    success_url = 'success'

Avec ces 3 attributs principaux définis, appelez-le dans vos URL.

('^authors/create/$', Author.AuthorCreateView.as_view()),

Rendez la page et vous verrez votre ModelForm passé au modèle en tant que form, en gérant l'étape de validation du formulaire (en passant request.POST/Re-render si invalide), ainsi qu'en appelant form.save() et rediriger vers le success_url.


Commencez à remplacer les méthodes de classe

Pour personnaliser le comportement, commencez à remplacer les méthodes documentées pour mixins.

N'oubliez pas que vous devez simplement renvoyer un HttpResponse à partir de l'une de ces méthodes, comme n'importe quelle fonction d'affichage standard.

Exemple de substitution de form_invalid Documenté dans ModelFormMixin:

class AuthorCreateView(CreateView):
    form_class = AuthorForm
    template_name = 'author_new.html'
    success_url = 'success'

    def form_invalid(self, form):
        return http.HttpResponse("form is invalid.. this is just an HttpResponse object")

Cette substitution par méthode commence à devenir extrêmement utile à mesure que vos formulaires deviennent plus avancés et vous permet finalement de créer d'énormes formulaires avec une poignée de lignes de code, remplaçant uniquement ce qui est nécessaire.

Supposons que vous souhaitiez transmettre les paramètres personnalisés de votre formulaire, tels que l'objet request (très courant si vous avez besoin d'accéder à l'utilisateur dans le formulaire): il vous suffit de remplacer get_form_kwargs.

class MyFormView(FormView):
    def get_form_kwargs(self):
        # pass "user" keyword argument with the current user to your form
        kwargs = super(MyFormView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

Les vues basées sur les classes sont un brillant exemple d'utilisation intelligente des classes. Cela m'a donné une excellente introduction à la création de mes propres mixins pour les vues et les classes python en général. Cela fait gagner un nombre incalculable d'heures.

Wow, c'est devenu long. Dire que cela a commencé comme une simple URL vers le commentaire de la documentation :) J'espère que ça aide!

184