Fixed #32271 -- Improved consistency of docs CBV examples.

Co-Authored-By: Carles Pina i Estany <carles@pina.cat>
This commit is contained in:
Jack Aitken 2021-03-01 16:54:22 -05:00 committed by Mariusz Felisiak
parent 73b1b225ce
commit 5fd4f22d19
8 changed files with 52 additions and 52 deletions

View File

@ -220,11 +220,11 @@ MRO is an acronym for Method Resolution Order.
from django.urls import path from django.urls import path
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView
from article.views import ArticleCounterRedirectView, ArticleDetail from article.views import ArticleCounterRedirectView, ArticleDetailView
urlpatterns = [ urlpatterns = [
path('counter/<int:pk>/', ArticleCounterRedirectView.as_view(), name='article-counter'), path('counter/<int:pk>/', ArticleCounterRedirectView.as_view(), name='article-counter'),
path('details/<int:pk>/', ArticleDetail.as_view(), name='article-detail'), path('details/<int:pk>/', ArticleDetailView.as_view(), name='article-detail'),
path('go-to-django/', RedirectView.as_view(url='https://djangoproject.com'), name='go-to-django'), path('go-to-django/', RedirectView.as_view(url='https://djangoproject.com'), name='go-to-django'),
] ]

View File

@ -65,7 +65,7 @@ editing content:
from myapp.forms import ContactForm from myapp.forms import ContactForm
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
class ContactView(FormView): class ContactFormView(FormView):
template_name = 'contact.html' template_name = 'contact.html'
form_class = ContactForm form_class = ContactForm
success_url = '/thanks/' success_url = '/thanks/'
@ -141,7 +141,7 @@ editing content:
from django.views.generic.edit import CreateView from django.views.generic.edit import CreateView
from myapp.models import Author from myapp.models import Author
class AuthorCreate(CreateView): class AuthorCreateView(CreateView):
model = Author model = Author
fields = ['name'] fields = ['name']
@ -220,7 +220,7 @@ editing content:
from django.views.generic.edit import UpdateView from django.views.generic.edit import UpdateView
from myapp.models import Author from myapp.models import Author
class AuthorUpdate(UpdateView): class AuthorUpdateView(UpdateView):
model = Author model = Author
fields = ['name'] fields = ['name']
template_name_suffix = '_update_form' template_name_suffix = '_update_form'
@ -295,7 +295,7 @@ editing content:
from django.views.generic.edit import DeleteView from django.views.generic.edit import DeleteView
from myapp.models import Author from myapp.models import Author
class AuthorDelete(DeleteView): class AuthorDeleteView(DeleteView):
model = Author model = Author
success_url = reverse_lazy('author-list') success_url = reverse_lazy('author-list')

View File

@ -369,7 +369,7 @@ Adding messages in class-based views
from django.views.generic.edit import CreateView from django.views.generic.edit import CreateView
from myapp.models import Author from myapp.models import Author
class AuthorCreate(SuccessMessageMixin, CreateView): class AuthorCreateView(SuccessMessageMixin, CreateView):
model = Author model = Author
success_url = '/success/' success_url = '/success/'
success_message = "%(name)s was created successfully" success_message = "%(name)s was created successfully"
@ -386,7 +386,7 @@ method.
from django.views.generic.edit import CreateView from django.views.generic.edit import CreateView
from myapp.models import ComplicatedModel from myapp.models import ComplicatedModel
class ComplicatedCreate(SuccessMessageMixin, CreateView): class ComplicatedCreateView(SuccessMessageMixin, CreateView):
model = ComplicatedModel model = ComplicatedModel
success_url = '/success/' success_url = '/success/'
success_message = "%(calculated_field)s was created successfully" success_message = "%(calculated_field)s was created successfully"

View File

@ -110,17 +110,17 @@ Now we need to define a view::
from django.views.generic import ListView from django.views.generic import ListView
from books.models import Publisher from books.models import Publisher
class PublisherList(ListView): class PublisherListView(ListView):
model = Publisher model = Publisher
Finally hook that view into your urls:: Finally hook that view into your urls::
# urls.py # urls.py
from django.urls import path from django.urls import path
from books.views import PublisherList from books.views import PublisherListView
urlpatterns = [ urlpatterns = [
path('publishers/', PublisherList.as_view()), path('publishers/', PublisherListView.as_view()),
] ]
That's all the Python code we need to write. We still need to write a template, That's all the Python code we need to write. We still need to write a template,
@ -183,7 +183,7 @@ specifies the context variable to use::
from django.views.generic import ListView from django.views.generic import ListView
from books.models import Publisher from books.models import Publisher
class PublisherList(ListView): class PublisherListView(ListView):
model = Publisher model = Publisher
context_object_name = 'my_favorite_publishers' context_object_name = 'my_favorite_publishers'
@ -210,7 +210,7 @@ you can override it to send more::
from django.views.generic import DetailView from django.views.generic import DetailView
from books.models import Book, Publisher from books.models import Book, Publisher
class PublisherDetail(DetailView): class PublisherDetailView(DetailView):
model = Publisher model = Publisher
@ -254,7 +254,7 @@ specify the list of objects using the ``queryset`` argument::
from django.views.generic import DetailView from django.views.generic import DetailView
from books.models import Publisher from books.models import Publisher
class PublisherDetail(DetailView): class PublisherDetailView(DetailView):
context_object_name = 'publisher' context_object_name = 'publisher'
queryset = Publisher.objects.all() queryset = Publisher.objects.all()
@ -273,7 +273,7 @@ with the most recent first::
from django.views.generic import ListView from django.views.generic import ListView
from books.models import Book from books.models import Book
class BookList(ListView): class BookListView(ListView):
queryset = Book.objects.order_by('-publication_date') queryset = Book.objects.order_by('-publication_date')
context_object_name = 'book_list' context_object_name = 'book_list'
@ -284,7 +284,7 @@ list of books by a particular publisher, you can use the same technique::
from django.views.generic import ListView from django.views.generic import ListView
from books.models import Book from books.models import Book
class AcmeBookList(ListView): class AcmeBookListView(ListView):
context_object_name = 'book_list' context_object_name = 'book_list'
queryset = Book.objects.filter(publisher__name='ACME Publishing') queryset = Book.objects.filter(publisher__name='ACME Publishing')
@ -330,20 +330,20 @@ Here, we have a URLconf with a single captured group::
# urls.py # urls.py
from django.urls import path from django.urls import path
from books.views import PublisherBookList from books.views import PublisherBookListView
urlpatterns = [ urlpatterns = [
path('books/<publisher>/', PublisherBookList.as_view()), path('books/<publisher>/', PublisherBookListView.as_view()),
] ]
Next, we'll write the ``PublisherBookList`` view itself:: Next, we'll write the ``PublisherBookListView`` view itself::
# views.py # views.py
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.views.generic import ListView from django.views.generic import ListView
from books.models import Book, Publisher from books.models import Book, Publisher
class PublisherBookList(ListView): class PublisherBookListView(ListView):
template_name = 'books/books_by_publisher.html' template_name = 'books/books_by_publisher.html'

View File

@ -39,7 +39,7 @@ The view can be constructed using a ``FormView``:
from myapp.forms import ContactForm from myapp.forms import ContactForm
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
class ContactView(FormView): class ContactFormView(FormView):
template_name = 'contact.html' template_name = 'contact.html'
form_class = ContactForm form_class = ContactForm
success_url = '/thanks/' success_url = '/thanks/'
@ -119,15 +119,15 @@ here; we don't have to write any logic ourselves:
from django.views.generic.edit import CreateView, DeleteView, UpdateView from django.views.generic.edit import CreateView, DeleteView, UpdateView
from myapp.models import Author from myapp.models import Author
class AuthorCreate(CreateView): class AuthorCreateView(CreateView):
model = Author model = Author
fields = ['name'] fields = ['name']
class AuthorUpdate(UpdateView): class AuthorUpdateView(UpdateView):
model = Author model = Author
fields = ['name'] fields = ['name']
class AuthorDelete(DeleteView): class AuthorDeleteView(DeleteView):
model = Author model = Author
success_url = reverse_lazy('author-list') success_url = reverse_lazy('author-list')
@ -150,13 +150,13 @@ Finally, we hook these new views into the URLconf:
:caption: urls.py :caption: urls.py
from django.urls import path from django.urls import path
from myapp.views import AuthorCreate, AuthorDelete, AuthorUpdate from myapp.views import AuthorCreateView, AuthorDeleteView, AuthorUpdateView
urlpatterns = [ urlpatterns = [
# ... # ...
path('author/add/', AuthorCreate.as_view(), name='author-add'), path('author/add/', AuthorCreateView.as_view(), name='author-add'),
path('author/<int:pk>/', AuthorUpdate.as_view(), name='author-update'), path('author/<int:pk>/', AuthorUpdateView.as_view(), name='author-update'),
path('author/<int:pk>/delete/', AuthorDelete.as_view(), name='author-delete'), path('author/<int:pk>/delete/', AuthorDeleteView.as_view(), name='author-delete'),
] ]
.. note:: .. note::
@ -210,7 +210,7 @@ to edit, and override
from django.views.generic.edit import CreateView from django.views.generic.edit import CreateView
from myapp.models import Author from myapp.models import Author
class AuthorCreate(LoginRequiredMixin, CreateView): class AuthorCreateView(LoginRequiredMixin, CreateView):
model = Author model = Author
fields = ['name'] fields = ['name']
@ -259,6 +259,6 @@ works with an API-based workflow as well as 'normal' form POSTs::
} }
return JsonResponse(data) return JsonResponse(data)
class AuthorCreate(JsonableResponseMixin, CreateView): class AuthorCreateView(JsonableResponseMixin, CreateView):
model = Author model = Author
fields = ['name'] fields = ['name']

View File

@ -229,7 +229,7 @@ We'll demonstrate this with the ``Author`` model we used in the
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from books.models import Author from books.models import Author
class RecordInterest(SingleObjectMixin, View): class RecordInterestView(SingleObjectMixin, View):
"""Records the current user's interest in an author.""" """Records the current user's interest in an author."""
model = Author model = Author
@ -256,11 +256,11 @@ We can hook this into our URLs easily enough:
:caption: urls.py :caption: urls.py
from django.urls import path from django.urls import path
from books.views import RecordInterest from books.views import RecordInterestView
urlpatterns = [ urlpatterns = [
#... #...
path('author/<int:pk>/interest/', RecordInterest.as_view(), name='author-interest'), path('author/<int:pk>/interest/', RecordInterestView.as_view(), name='author-interest'),
] ]
Note the ``pk`` named group, which Note the ``pk`` named group, which
@ -307,13 +307,13 @@ object. In order to do this, we need to have two different querysets:
will add in the suitable ``page_obj`` and ``paginator`` for us will add in the suitable ``page_obj`` and ``paginator`` for us
providing we remember to call ``super()``. providing we remember to call ``super()``.
Now we can write a new ``PublisherDetail``:: Now we can write a new ``PublisherDetailView``::
from django.views.generic import ListView from django.views.generic import ListView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from books.models import Publisher from books.models import Publisher
class PublisherDetail(SingleObjectMixin, ListView): class PublisherDetailView(SingleObjectMixin, ListView):
paginate_by = 2 paginate_by = 2
template_name = "books/publisher_detail.html" template_name = "books/publisher_detail.html"
@ -434,7 +434,7 @@ code so that on ``POST`` the form gets called appropriately.
both of the views implement ``get()``, and things would get much more both of the views implement ``get()``, and things would get much more
confusing. confusing.
Our new ``AuthorDetail`` looks like this:: Our new ``AuthorDetailView`` looks like this::
# CAUTION: you almost certainly do not want to do this. # CAUTION: you almost certainly do not want to do this.
# It is provided as part of a discussion of problems you can # It is provided as part of a discussion of problems you can
@ -451,7 +451,7 @@ Our new ``AuthorDetail`` looks like this::
class AuthorInterestForm(forms.Form): class AuthorInterestForm(forms.Form):
message = forms.CharField() message = forms.CharField()
class AuthorDetail(FormMixin, DetailView): class AuthorDetailView(FormMixin, DetailView):
model = Author model = Author
form_class = AuthorInterestForm form_class = AuthorInterestForm
@ -504,8 +504,8 @@ clear division here: ``GET`` requests should get the
data), and ``POST`` requests should get the :class:`FormView`. Let's data), and ``POST`` requests should get the :class:`FormView`. Let's
set up those views first. set up those views first.
The ``AuthorDisplay`` view is almost the same as :ref:`when we The ``AuthorDetailView`` view is almost the same as :ref:`when we
first introduced AuthorDetail<generic-views-extra-work>`; we have to first introduced AuthorDetailView<generic-views-extra-work>`; we have to
write our own ``get_context_data()`` to make the write our own ``get_context_data()`` to make the
``AuthorInterestForm`` available to the template. We'll skip the ``AuthorInterestForm`` available to the template. We'll skip the
``get_object()`` override from before for clarity:: ``get_object()`` override from before for clarity::
@ -517,7 +517,7 @@ write our own ``get_context_data()`` to make the
class AuthorInterestForm(forms.Form): class AuthorInterestForm(forms.Form):
message = forms.CharField() message = forms.CharField()
class AuthorDisplay(DetailView): class AuthorDetailView(DetailView):
model = Author model = Author
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -525,18 +525,18 @@ write our own ``get_context_data()`` to make the
context['form'] = AuthorInterestForm() context['form'] = AuthorInterestForm()
return context return context
Then the ``AuthorInterest`` is a :class:`FormView`, but we have to bring in Then the ``AuthorInterestForm`` is a :class:`FormView`, but we have to bring in
:class:`~django.views.generic.detail.SingleObjectMixin` so we can find the :class:`~django.views.generic.detail.SingleObjectMixin` so we can find the
author we're talking about, and we have to remember to set ``template_name`` to author we're talking about, and we have to remember to set ``template_name`` to
ensure that form errors will render the same template as ``AuthorDisplay`` is ensure that form errors will render the same template as ``AuthorDetailView``
using on ``GET``:: is using on ``GET``::
from django.http import HttpResponseForbidden from django.http import HttpResponseForbidden
from django.urls import reverse from django.urls import reverse
from django.views.generic import FormView from django.views.generic import FormView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
class AuthorInterest(SingleObjectMixin, FormView): class AuthorInterestFormView(SingleObjectMixin, FormView):
template_name = 'books/author_detail.html' template_name = 'books/author_detail.html'
form_class = AuthorInterestForm form_class = AuthorInterestForm
model = Author model = Author
@ -550,26 +550,26 @@ using on ``GET``::
def get_success_url(self): def get_success_url(self):
return reverse('author-detail', kwargs={'pk': self.object.pk}) return reverse('author-detail', kwargs={'pk': self.object.pk})
Finally we bring this together in a new ``AuthorDetail`` view. We Finally we bring this together in a new ``AuthorView`` view. We
already know that calling :meth:`~django.views.generic.base.View.as_view()` on already know that calling :meth:`~django.views.generic.base.View.as_view()` on
a class-based view gives us something that behaves exactly like a function a class-based view gives us something that behaves exactly like a function
based view, so we can do that at the point we choose between the two subviews. based view, so we can do that at the point we choose between the two subviews.
You can pass through keyword arguments to You can pass through keyword arguments to
:meth:`~django.views.generic.base.View.as_view()` in the same way you :meth:`~django.views.generic.base.View.as_view()` in the same way you
would in your URLconf, such as if you wanted the ``AuthorInterest`` behavior would in your URLconf, such as if you wanted the ``AuthorInterestFormView``
to also appear at another URL but using a different template:: behavior to also appear at another URL but using a different template::
from django.views import View from django.views import View
class AuthorDetail(View): class AuthorView(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
view = AuthorDisplay.as_view() view = AuthorDetailView.as_view()
return view(request, *args, **kwargs) return view(request, *args, **kwargs)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
view = AuthorInterest.as_view() view = AuthorInterestFormView.as_view()
return view(request, *args, **kwargs) return view(request, *args, **kwargs)
This approach can also be used with any other generic class-based This approach can also be used with any other generic class-based

View File

@ -150,7 +150,7 @@ uploads:
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from .forms import FileFieldForm from .forms import FileFieldForm
class FileFieldView(FormView): class FileFieldFormView(FormView):
form_class = FileFieldForm form_class = FileFieldForm
template_name = 'upload.html' # Replace with your template. template_name = 'upload.html' # Replace with your template.
success_url = '...' # Replace with your URL or reverse(). success_url = '...' # Replace with your URL or reverse().

View File

@ -90,7 +90,7 @@ your view class, for example::
from myapp.models import Contact from myapp.models import Contact
class ContactList(ListView): class ContactListView(ListView):
paginate_by = 2 paginate_by = 2
model = Contact model = Contact