mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	- Updated references to RFC 1123 to RFC 5322 - Only partial as RFC 5322 sort of sub-references RFC 1123. - Updated references to RFC 2388 to RFC 7578 - Except RFC 2388 Section 5.3 which has no equivalent. - Updated references to RFC 2396 to RFC 3986 - Updated references to RFC 2616 to RFC 9110 - Updated references to RFC 3066 to RFC 5646 - Updated references to RFC 7230 to RFC 9112 - Updated references to RFC 7231 to RFC 9110 - Updated references to RFC 7232 to RFC 9110 - Updated references to RFC 7234 to RFC 9111 - Tidied up style of text when referring to RFC documents
		
			
				
	
	
		
			427 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			427 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import json
 | |
| from urllib.parse import urlencode
 | |
| from xml.dom.minidom import parseString
 | |
| 
 | |
| from django.contrib.auth.decorators import login_required, permission_required
 | |
| from django.core import mail
 | |
| from django.core.exceptions import ValidationError
 | |
| from django.forms import fields
 | |
| from django.forms.forms import Form
 | |
| from django.http import (
 | |
|     HttpResponse,
 | |
|     HttpResponseBadRequest,
 | |
|     HttpResponseNotAllowed,
 | |
|     HttpResponseNotFound,
 | |
|     HttpResponseRedirect,
 | |
| )
 | |
| from django.shortcuts import render
 | |
| from django.template import Context, Template
 | |
| from django.test import Client
 | |
| from django.utils.decorators import method_decorator
 | |
| from django.views.generic import TemplateView
 | |
| 
 | |
| 
 | |
| def get_view(request):
 | |
|     "A simple view that expects a GET request, and returns a rendered template"
 | |
|     t = Template("This is a test. {{ var }} is the value.", name="GET Template")
 | |
|     c = Context({"var": request.GET.get("var", 42)})
 | |
| 
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| async def async_get_view(request):
 | |
|     return HttpResponse(b"GET content.")
 | |
| 
 | |
| 
 | |
| def trace_view(request):
 | |
|     """
 | |
|     A simple view that expects a TRACE request and echoes its status line.
 | |
| 
 | |
|     TRACE requests should not have an entity; the view will return a 400 status
 | |
|     response if it is present.
 | |
|     """
 | |
|     if request.method.upper() != "TRACE":
 | |
|         return HttpResponseNotAllowed("TRACE")
 | |
|     elif request.body:
 | |
|         return HttpResponseBadRequest("TRACE requests MUST NOT include an entity")
 | |
|     else:
 | |
|         protocol = request.META["SERVER_PROTOCOL"]
 | |
|         t = Template(
 | |
|             "{{ method }} {{ uri }} {{ version }}",
 | |
|             name="TRACE Template",
 | |
|         )
 | |
|         c = Context(
 | |
|             {
 | |
|                 "method": request.method,
 | |
|                 "uri": request.path,
 | |
|                 "version": protocol,
 | |
|             }
 | |
|         )
 | |
|         return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def put_view(request):
 | |
|     if request.method == "PUT":
 | |
|         t = Template("Data received: {{ data }} is the body.", name="PUT Template")
 | |
|         c = Context(
 | |
|             {
 | |
|                 "Content-Length": request.META["CONTENT_LENGTH"],
 | |
|                 "data": request.body.decode(),
 | |
|             }
 | |
|         )
 | |
|     else:
 | |
|         t = Template("Viewing GET page.", name="Empty GET Template")
 | |
|         c = Context()
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def post_view(request):
 | |
|     """A view that expects a POST, and returns a different template depending
 | |
|     on whether any POST data is available
 | |
|     """
 | |
|     if request.method == "POST":
 | |
|         if request.POST:
 | |
|             t = Template(
 | |
|                 "Data received: {{ data }} is the value.", name="POST Template"
 | |
|             )
 | |
|             c = Context({"data": request.POST["value"]})
 | |
|         else:
 | |
|             t = Template("Viewing POST page.", name="Empty POST Template")
 | |
|             c = Context()
 | |
|     else:
 | |
|         t = Template("Viewing GET page.", name="Empty GET Template")
 | |
|         # Used by test_body_read_on_get_data.
 | |
|         request.read(200)
 | |
|         c = Context()
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def post_then_get_view(request):
 | |
|     """
 | |
|     A view that expects a POST request, returns a redirect response
 | |
|     to itself providing only a ?success=true querystring,
 | |
|     the value of this querystring is then rendered upon GET.
 | |
|     """
 | |
|     if request.method == "POST":
 | |
|         return HttpResponseRedirect("?success=true")
 | |
| 
 | |
|     t = Template("The value of success is {{ value }}.", name="GET Template")
 | |
|     c = Context({"value": request.GET.get("success", "false")})
 | |
| 
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def json_view(request):
 | |
|     """
 | |
|     A view that expects a request with the header 'application/json' and JSON
 | |
|     data, which is deserialized and included in the context.
 | |
|     """
 | |
|     if request.META.get("CONTENT_TYPE") != "application/json":
 | |
|         return HttpResponse()
 | |
| 
 | |
|     t = Template("Viewing {} page. With data {{ data }}.".format(request.method))
 | |
|     data = json.loads(request.body.decode("utf-8"))
 | |
|     c = Context({"data": data})
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def view_with_header(request):
 | |
|     "A view that has a custom header"
 | |
|     response = HttpResponse()
 | |
|     response.headers["X-DJANGO-TEST"] = "Slartibartfast"
 | |
|     return response
 | |
| 
 | |
| 
 | |
| def raw_post_view(request):
 | |
|     """A view which expects raw XML to be posted and returns content extracted
 | |
|     from the XML"""
 | |
|     if request.method == "POST":
 | |
|         root = parseString(request.body)
 | |
|         first_book = root.firstChild.firstChild
 | |
|         title, author = [n.firstChild.nodeValue for n in first_book.childNodes]
 | |
|         t = Template("{{ title }} - {{ author }}", name="Book template")
 | |
|         c = Context({"title": title, "author": author})
 | |
|     else:
 | |
|         t = Template("GET request.", name="Book GET template")
 | |
|         c = Context()
 | |
| 
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def redirect_view(request):
 | |
|     "A view that redirects all requests to the GET view"
 | |
|     if request.GET:
 | |
|         query = "?" + urlencode(request.GET, True)
 | |
|     else:
 | |
|         query = ""
 | |
|     return HttpResponseRedirect("/get_view/" + query)
 | |
| 
 | |
| 
 | |
| def method_saving_307_redirect_query_string_view(request):
 | |
|     return HttpResponseRedirect("/post_view/?hello=world", status=307)
 | |
| 
 | |
| 
 | |
| def method_saving_308_redirect_query_string_view(request):
 | |
|     return HttpResponseRedirect("/post_view/?hello=world", status=308)
 | |
| 
 | |
| 
 | |
| def _post_view_redirect(request, status_code):
 | |
|     """Redirect to /post_view/ using the status code."""
 | |
|     redirect_to = request.GET.get("to", "/post_view/")
 | |
|     return HttpResponseRedirect(redirect_to, status=status_code)
 | |
| 
 | |
| 
 | |
| def method_saving_307_redirect_view(request):
 | |
|     return _post_view_redirect(request, 307)
 | |
| 
 | |
| 
 | |
| def method_saving_308_redirect_view(request):
 | |
|     return _post_view_redirect(request, 308)
 | |
| 
 | |
| 
 | |
| def view_with_secure(request):
 | |
|     "A view that indicates if the request was secure"
 | |
|     response = HttpResponse()
 | |
|     response.test_was_secure_request = request.is_secure()
 | |
|     response.test_server_port = request.META.get("SERVER_PORT", 80)
 | |
|     return response
 | |
| 
 | |
| 
 | |
| def double_redirect_view(request):
 | |
|     "A view that redirects all requests to a redirection view"
 | |
|     return HttpResponseRedirect("/permanent_redirect_view/")
 | |
| 
 | |
| 
 | |
| def bad_view(request):
 | |
|     "A view that returns a 404 with some error content"
 | |
|     return HttpResponseNotFound("Not found!. This page contains some MAGIC content")
 | |
| 
 | |
| 
 | |
| TestChoices = (
 | |
|     ("a", "First Choice"),
 | |
|     ("b", "Second Choice"),
 | |
|     ("c", "Third Choice"),
 | |
|     ("d", "Fourth Choice"),
 | |
|     ("e", "Fifth Choice"),
 | |
| )
 | |
| 
 | |
| 
 | |
| class TestForm(Form):
 | |
|     text = fields.CharField()
 | |
|     email = fields.EmailField()
 | |
|     value = fields.IntegerField()
 | |
|     single = fields.ChoiceField(choices=TestChoices)
 | |
|     multi = fields.MultipleChoiceField(choices=TestChoices)
 | |
| 
 | |
|     def clean(self):
 | |
|         cleaned_data = self.cleaned_data
 | |
|         if cleaned_data.get("text") == "Raise non-field error":
 | |
|             raise ValidationError("Non-field error.")
 | |
|         return cleaned_data
 | |
| 
 | |
| 
 | |
| def form_view(request):
 | |
|     "A view that tests a simple form"
 | |
|     if request.method == "POST":
 | |
|         form = TestForm(request.POST)
 | |
|         if form.is_valid():
 | |
|             t = Template("Valid POST data.", name="Valid POST Template")
 | |
|             c = Context()
 | |
|         else:
 | |
|             t = Template(
 | |
|                 "Invalid POST data. {{ form.errors }}", name="Invalid POST Template"
 | |
|             )
 | |
|             c = Context({"form": form})
 | |
|     else:
 | |
|         form = TestForm(request.GET)
 | |
|         t = Template("Viewing base form. {{ form }}.", name="Form GET Template")
 | |
|         c = Context({"form": form})
 | |
| 
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def form_view_with_template(request):
 | |
|     "A view that tests a simple form"
 | |
|     if request.method == "POST":
 | |
|         form = TestForm(request.POST)
 | |
|         if form.is_valid():
 | |
|             message = "POST data OK"
 | |
|         else:
 | |
|             message = "POST data has errors"
 | |
|     else:
 | |
|         form = TestForm()
 | |
|         message = "GET form page"
 | |
|     return render(
 | |
|         request,
 | |
|         "form_view.html",
 | |
|         {
 | |
|             "form": form,
 | |
|             "message": message,
 | |
|         },
 | |
|     )
 | |
| 
 | |
| 
 | |
| @login_required
 | |
| def login_protected_view(request):
 | |
|     "A simple view that is login protected."
 | |
|     t = Template(
 | |
|         "This is a login protected test. Username is {{ user.username }}.",
 | |
|         name="Login Template",
 | |
|     )
 | |
|     c = Context({"user": request.user})
 | |
| 
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| @login_required(redirect_field_name="redirect_to")
 | |
| def login_protected_view_changed_redirect(request):
 | |
|     "A simple view that is login protected with a custom redirect field set"
 | |
|     t = Template(
 | |
|         "This is a login protected test. Username is {{ user.username }}.",
 | |
|         name="Login Template",
 | |
|     )
 | |
|     c = Context({"user": request.user})
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def _permission_protected_view(request):
 | |
|     "A simple view that is permission protected."
 | |
|     t = Template(
 | |
|         "This is a permission protected test. "
 | |
|         "Username is {{ user.username }}. "
 | |
|         "Permissions are {{ user.get_all_permissions }}.",
 | |
|         name="Permissions Template",
 | |
|     )
 | |
|     c = Context({"user": request.user})
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| permission_protected_view = permission_required("permission_not_granted")(
 | |
|     _permission_protected_view
 | |
| )
 | |
| permission_protected_view_exception = permission_required(
 | |
|     "permission_not_granted", raise_exception=True
 | |
| )(_permission_protected_view)
 | |
| 
 | |
| 
 | |
| class _ViewManager:
 | |
|     @method_decorator(login_required)
 | |
|     def login_protected_view(self, request):
 | |
|         t = Template(
 | |
|             "This is a login protected test using a method. "
 | |
|             "Username is {{ user.username }}.",
 | |
|             name="Login Method Template",
 | |
|         )
 | |
|         c = Context({"user": request.user})
 | |
|         return HttpResponse(t.render(c))
 | |
| 
 | |
|     @method_decorator(permission_required("permission_not_granted"))
 | |
|     def permission_protected_view(self, request):
 | |
|         t = Template(
 | |
|             "This is a permission protected test using a method. "
 | |
|             "Username is {{ user.username }}. "
 | |
|             "Permissions are {{ user.get_all_permissions }}.",
 | |
|             name="Permissions Template",
 | |
|         )
 | |
|         c = Context({"user": request.user})
 | |
|         return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| _view_manager = _ViewManager()
 | |
| login_protected_method_view = _view_manager.login_protected_view
 | |
| permission_protected_method_view = _view_manager.permission_protected_view
 | |
| 
 | |
| 
 | |
| def session_view(request):
 | |
|     "A view that modifies the session"
 | |
|     request.session["tobacconist"] = "hovercraft"
 | |
| 
 | |
|     t = Template(
 | |
|         "This is a view that modifies the session.",
 | |
|         name="Session Modifying View Template",
 | |
|     )
 | |
|     c = Context()
 | |
|     return HttpResponse(t.render(c))
 | |
| 
 | |
| 
 | |
| def broken_view(request):
 | |
|     """A view which just raises an exception, simulating a broken view."""
 | |
|     raise KeyError("Oops! Looks like you wrote some bad code.")
 | |
| 
 | |
| 
 | |
| def mail_sending_view(request):
 | |
|     mail.EmailMessage(
 | |
|         "Test message",
 | |
|         "This is a test email",
 | |
|         "from@example.com",
 | |
|         ["first@example.com", "second@example.com"],
 | |
|     ).send()
 | |
|     return HttpResponse("Mail sent")
 | |
| 
 | |
| 
 | |
| def mass_mail_sending_view(request):
 | |
|     m1 = mail.EmailMessage(
 | |
|         "First Test message",
 | |
|         "This is the first test email",
 | |
|         "from@example.com",
 | |
|         ["first@example.com", "second@example.com"],
 | |
|     )
 | |
|     m2 = mail.EmailMessage(
 | |
|         "Second Test message",
 | |
|         "This is the second test email",
 | |
|         "from@example.com",
 | |
|         ["second@example.com", "third@example.com"],
 | |
|     )
 | |
| 
 | |
|     c = mail.get_connection()
 | |
|     c.send_messages([m1, m2])
 | |
| 
 | |
|     return HttpResponse("Mail sent")
 | |
| 
 | |
| 
 | |
| def nesting_exception_view(request):
 | |
|     """
 | |
|     A view that uses a nested client to call another view and then raises an
 | |
|     exception.
 | |
|     """
 | |
|     client = Client()
 | |
|     client.get("/get_view/")
 | |
|     raise Exception("exception message")
 | |
| 
 | |
| 
 | |
| def django_project_redirect(request):
 | |
|     return HttpResponseRedirect("https://www.djangoproject.com/")
 | |
| 
 | |
| 
 | |
| def no_trailing_slash_external_redirect(request):
 | |
|     """
 | |
|     RFC 3986 Section 6.2.3: Empty path should be normalized to "/".
 | |
| 
 | |
|     Use https://testserver, rather than an external domain, in order to allow
 | |
|     use of follow=True, triggering Client._handle_redirects().
 | |
|     """
 | |
|     return HttpResponseRedirect("https://testserver")
 | |
| 
 | |
| 
 | |
| def index_view(request):
 | |
|     """Target for no_trailing_slash_external_redirect with follow=True."""
 | |
|     return HttpResponse("Hello world")
 | |
| 
 | |
| 
 | |
| def upload_view(request):
 | |
|     """Prints keys of request.FILES to the response."""
 | |
|     return HttpResponse(", ".join(request.FILES))
 | |
| 
 | |
| 
 | |
| class TwoArgException(Exception):
 | |
|     def __init__(self, one, two):
 | |
|         pass
 | |
| 
 | |
| 
 | |
| def two_arg_exception(request):
 | |
|     raise TwoArgException("one", "two")
 | |
| 
 | |
| 
 | |
| class CBView(TemplateView):
 | |
|     template_name = "base.html"
 |