django/tests/generic_views/views.py

353 lines
8.4 KiB
Python

from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.urls import reverse, reverse_lazy
from django.utils.decorators import method_decorator
from django.views import generic
from .forms import AuthorForm, ConfirmDeleteForm, ContactForm
from .models import Artist, Author, Book, BookSigning, Page
class CustomTemplateView(generic.TemplateView):
template_name = "generic_views/about.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({"key": "value"})
return context
class ObjectDetail(generic.DetailView):
template_name = "generic_views/detail.html"
def get_object(self):
return {"foo": "bar"}
class ArtistDetail(generic.DetailView):
queryset = Artist.objects.all()
class AuthorDetail(generic.DetailView):
queryset = Author.objects.all()
class AuthorCustomDetail(generic.DetailView):
template_name = "generic_views/author_detail.html"
queryset = Author.objects.all()
def get(self, request, *args, **kwargs):
# Ensures get_context_object_name() doesn't reference self.object.
author = self.get_object()
context = {"custom_" + self.get_context_object_name(author): author}
return self.render_to_response(context)
class PageDetail(generic.DetailView):
queryset = Page.objects.all()
template_name_field = "template"
class DictList(generic.ListView):
"""A ListView that doesn't use a model."""
queryset = [{"first": "John", "last": "Lennon"}, {"first": "Yoko", "last": "Ono"}]
template_name = "generic_views/list.html"
class ArtistList(generic.ListView):
template_name = "generic_views/list.html"
queryset = Artist.objects.all()
class AuthorList(generic.ListView):
queryset = Author.objects.all()
class AuthorListGetQuerysetReturnsNone(AuthorList):
def get_queryset(self):
return None
class BookList(generic.ListView):
model = Book
class CustomPaginator(Paginator):
def __init__(self, queryset, page_size, orphans=0, allow_empty_first_page=True):
super().__init__(
queryset,
page_size,
orphans=2,
allow_empty_first_page=allow_empty_first_page,
)
class AuthorListCustomPaginator(AuthorList):
paginate_by = 5
def get_paginator(
self, queryset, page_size, orphans=0, allow_empty_first_page=True
):
return super().get_paginator(
queryset,
page_size,
orphans=2,
allow_empty_first_page=allow_empty_first_page,
)
class ContactView(generic.FormView):
form_class = ContactForm
success_url = reverse_lazy("authors_list")
template_name = "generic_views/form.html"
class ArtistCreate(generic.CreateView):
model = Artist
fields = "__all__"
class NaiveAuthorCreate(generic.CreateView):
queryset = Author.objects.all()
fields = "__all__"
class TemplateResponseWithoutTemplate(
generic.detail.SingleObjectTemplateResponseMixin, generic.View
):
# we don't define the usual template_name here
def __init__(self):
# Dummy object, but attr is required by get_template_name()
self.object = None
class AuthorCreate(generic.CreateView):
model = Author
success_url = "/list/authors/"
fields = "__all__"
class SpecializedAuthorCreate(generic.CreateView):
model = Author
form_class = AuthorForm
template_name = "generic_views/form.html"
context_object_name = "thingy"
def get_success_url(self):
return reverse("author_detail", args=[self.object.id])
class AuthorCreateRestricted(AuthorCreate):
post = method_decorator(login_required)(AuthorCreate.post)
class ArtistUpdate(generic.UpdateView):
model = Artist
fields = "__all__"
class NaiveAuthorUpdate(generic.UpdateView):
queryset = Author.objects.all()
fields = "__all__"
class AuthorUpdate(generic.UpdateView):
get_form_called_count = 0 # Used to ensure get_form() is called once.
model = Author
success_url = "/list/authors/"
fields = "__all__"
def get_form(self, *args, **kwargs):
self.get_form_called_count += 1
return super().get_form(*args, **kwargs)
class OneAuthorUpdate(generic.UpdateView):
success_url = "/list/authors/"
fields = "__all__"
def get_object(self):
return Author.objects.get(pk=1)
class SpecializedAuthorUpdate(generic.UpdateView):
model = Author
form_class = AuthorForm
template_name = "generic_views/form.html"
context_object_name = "thingy"
def get_success_url(self):
return reverse("author_detail", args=[self.object.id])
class NaiveAuthorDelete(generic.DeleteView):
queryset = Author.objects.all()
class AuthorDelete(generic.DeleteView):
model = Author
success_url = "/list/authors/"
class AuthorDeleteFormView(generic.DeleteView):
model = Author
form_class = ConfirmDeleteForm
def get_success_url(self):
return reverse("authors_list")
class SpecializedAuthorDelete(generic.DeleteView):
queryset = Author.objects.all()
template_name = "generic_views/confirm_delete.html"
context_object_name = "thingy"
success_url = reverse_lazy("authors_list")
class BookConfig:
queryset = Book.objects.all()
date_field = "pubdate"
class BookArchive(BookConfig, generic.ArchiveIndexView):
pass
class BookYearArchive(BookConfig, generic.YearArchiveView):
pass
class BookMonthArchive(BookConfig, generic.MonthArchiveView):
pass
class BookWeekArchive(BookConfig, generic.WeekArchiveView):
pass
class BookDayArchive(BookConfig, generic.DayArchiveView):
pass
class BookTodayArchive(BookConfig, generic.TodayArchiveView):
pass
class BookDetail(BookConfig, generic.DateDetailView):
pass
class AuthorGetQuerySetFormView(generic.edit.ModelFormMixin):
fields = "__all__"
def get_queryset(self):
return Author.objects.all()
class BookDetailGetObjectCustomQueryset(BookDetail):
def get_object(self, queryset=None):
return super().get_object(queryset=Book.objects.filter(pk=self.kwargs["pk"]))
class CustomMultipleObjectMixinView(generic.list.MultipleObjectMixin, generic.View):
queryset = [
{"name": "John"},
{"name": "Yoko"},
]
def get(self, request):
self.object_list = self.get_queryset()
class CustomContextView(generic.detail.SingleObjectMixin, generic.View):
model = Book
object = Book(name="dummy")
def get_object(self):
return Book(name="dummy")
def get_context_data(self, **kwargs):
context = {"custom_key": "custom_value"}
context.update(kwargs)
return super().get_context_data(**context)
def get_context_object_name(self, obj):
return "test_name"
class CustomSingleObjectView(generic.detail.SingleObjectMixin, generic.View):
model = Book
object = Book(name="dummy")
class BookSigningConfig:
model = BookSigning
date_field = "event_date"
# use the same templates as for books
def get_template_names(self):
return ["generic_views/book%s.html" % self.template_name_suffix]
class BookSigningArchive(BookSigningConfig, generic.ArchiveIndexView):
pass
class BookSigningYearArchive(BookSigningConfig, generic.YearArchiveView):
pass
class BookSigningMonthArchive(BookSigningConfig, generic.MonthArchiveView):
pass
class BookSigningWeekArchive(BookSigningConfig, generic.WeekArchiveView):
pass
class BookSigningDayArchive(BookSigningConfig, generic.DayArchiveView):
pass
class BookSigningTodayArchive(BookSigningConfig, generic.TodayArchiveView):
pass
class BookArchiveWithoutDateField(generic.ArchiveIndexView):
queryset = Book.objects.all()
class BookSigningDetail(BookSigningConfig, generic.DateDetailView):
context_object_name = "book"
class NonModel:
id = "non_model_1"
_meta = None
class NonModelDetail(generic.DetailView):
template_name = "generic_views/detail.html"
model = NonModel
def get_object(self, queryset=None):
return NonModel()
class ObjectDoesNotExistDetail(generic.DetailView):
def get_queryset(self):
return Book.does_not_exist.all()
class LateValidationView(generic.FormView):
form_class = ContactForm
success_url = reverse_lazy("authors_list")
template_name = "generic_views/form.html"
def form_valid(self, form):
form.add_error(None, "There is an error")
return self.form_invalid(form)