All notes
HandleHTTP

Shortcut Functions

Package: django.shortcuts.

It collects helper functions and classes that "span" multiple levels of MVC. These functions/classes introduce controlled coupling for convenience’s sake.

render()

render(request, template_name, context=None, content_type=None, status=None, using=None)

"content_type" defaults to the value of the DEFAULT_CONTENT_TYPE setting.

"using": The NAME of a template engine to use for loading the template.


from django.shortcuts import render

def my_view(request):
    return render(request, 'myapp/index.html', {"foo": "bar"},
        content_type="application/xhtml+xml")

##########
# This example is equivalent to:

from django.http import HttpResponse
from django.template import loader

def my_view(request):
    t = loader.get_template('myapp/index.html')
    c = {'foo': 'bar'}
    return HttpResponse(t.render(c, request),
        content_type="application/xhtml+xml")

redirect()

redirect(to, permanent=False, *args, **kwargs)

to can be:


from django.shortcuts import redirect

def my_view(request):
    object = MyModel.objects.get(...)
    return redirect(object)

def my_view(request):
    return redirect('some-view-name', foo='bar')

def my_view(request):
    return redirect('/some/url/')
    // or full URL:
    return redirect('https://example.com/')

get_object_or_404()

get_object_or_404(klass, *args, **kwargs)

Calls get() on a given model manager, but it raises Http404 instead of the model’s DoesNotExist exception.

from django.shortcuts import get_object_or_404

def my_view(request):
    my_object = get_object_or_404(MyModel, pk=1)

##########
# This example is equivalent to:

from django.http import Http404

def my_view(request):
    try:
        my_object = MyModel.objects.get(pk=1)
    except MyModel.DoesNotExist:
        raise Http404("No MyModel matches the given query.")

Used on QuerySet:


queryset = Book.objects.filter(title__startswith='M')
get_object_or_404(queryset, pk=1)

// Equivalent to:
get_object_or_404(Book, title__startswith='M', pk=1)

get_list_or_404()


from django.shortcuts import get_list_or_404

def my_view(request):
    my_objects = get_list_or_404(MyModel, published=True)

##########
# This example is equivalent to:

from django.http import Http404

def my_view(request):
    my_objects = list(MyModel.objects.filter(published=True))
    if not my_objects:
        raise Http404("No MyModel matches the given query.")

File Uploads

DjangoProject: file uploads.

When Django handles a file upload, the file data ends up placed in request.FILES.

request.FILES will only contain data if the request method was POST and the "form" that posted the request has the attribute enctype="multipart/form-data".


##########
# In forms.py...
from django import forms

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    # the data would be accessible as request.FILES['file'].
    file = forms.FileField()

Binding uploaded files to a form:


from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm

# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file

def upload_file(request):
    if request.method == 'POST':
        # NOTE: we have to pass request.FILES into the form’s constructor to bind:
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render(request, 'upload.html', {'form': form})

def handle_uploaded_file(f):
    with open('some/file/name.txt', 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)
# Looping over UploadedFile.chunks() instead of using read() ensures that large files don’t overwhelm your system’s memory.

The file object will be saved to the location specified by the upload_to argument of the corresponding FileField when calling form.save().


from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ModelFormWithFileField

def upload_file(request):
    if request.method == 'POST':
        form = ModelFormWithFileField(request.POST, request.FILES)
        if form.is_valid():
            # file is saved
            form.save()
            return HttpResponseRedirect('/success/url/')
    else:
        form = ModelFormWithFileField()
    return render(request, 'upload.html', {'form': form})

Simply assign the file object from request.FILES to the file field in the model and save():


from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
from .models import ModelWithFileField

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            instance = ModelWithFileField(file_field=request.FILES['file'])
            instance.save()
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render(request, 'upload.html', {'form': form})

Upload Handlers

FILE_UPLOAD_HANDLERS setting defaults to:

["django.core.files.uploadhandler.MemoryFileUploadHandler",
 "django.core.files.uploadhandler.TemporaryFileUploadHandler"]

They together provide Django’s default file upload behavior of reading small files (smaller than 2.5MB) into memory and large ones onto disk (such as /tmp/tmpzfp6I6.upload).

You can override upload handlers on a per-request basis by modifying request.upload_handlers.


request.upload_handlers.insert(0, ProgressBarUploadHandler())