Представление — это то, что принимает запрос и возвращает какой-то ответ.

в render() функцию, вы можете передать context это переменные, которые вы можете передать в свой шаблон.


как добавить новый вид

  • определить URL-адрес в your-project/your-app/urls.py
  • добавить представление в your-projects/your-app/views/new-view.py
  • импортировать представление в your-projects/your-app/views/__init__.py


ярлыки: рендеринг, перенаправление

from django.shortcuts import render, redirect

def index(request):
  students = Students.objects.all()
  context = { "students": students }
  return render("index.html", context)

def new(request):
  # save a new student
  return redirect("your_app:new")
Войти в полноэкранный режим

Выйти из полноэкранного режима

Обратите внимание, что вы не можете передать контекст с redirect; вы можете передать только URL-адрес и параметры запроса.


Сообщения

Если вы хотите использовать «сообщения» (например, флэш-сообщения, всплывающие сообщения в других фреймворках), вы можете использовать фреймворк сообщений.

Добавьте этот импорт,

from django.contrib import messages
Войти в полноэкранный режим

Выйти из полноэкранного режима

… и вызывайте подобные сообщения в своих представлениях.

messages.debug(request, '%s SQL statements were executed.' % count)
messages.info(request, 'Three credits remain in your account.')
messages.success(request, 'Profile details updated.')
messages.warning(request, 'Your account expires in three days.')
messages.error(request, 'Document deleted.')
Войти в полноэкранный режим

Выйти из полноэкранного режима

Шаблон может отображать сообщения следующим образом:

{% if messages %}
<ul class="messages">
    {% for message in messages %}
    <li>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Важно повторять все сообщения, иначе сообщения не будут очищены.

from django.contrib import messages

# view to create new student
def new(request):
  if request.method == "POST":
    # do something with the form 
    student.save()
    # send messages
    messages.success(request, "saved student")
Войти в полноэкранный режим

Выйти из полноэкранного режима


наборы форм

Вы можете использовать наборы форм, когда хотите обрабатывать несколько записей одной и той же модели (например, нескольких студентов).

Наборы форм пригодятся, потому что они будут проверять все записи за вас.

На ваш взгляд, вы можете определить свой набор форм следующим образом:

# your_project/your_app/views/new.py

from django.forms import modelformset_factory
from django.shortcuts import redirect, render

from your_app.models import Student

def new(request):
  # fields: defines which fields to show in the form
  # extra: defines how many extra rows you want in the form, on top of existing records
  StudentFormset = modelformset_factory(Student, fields=["last_name", "first_name", "photo"], extra=10)

  if request.method == "GET":
    # by default, formset will populate all records in that model
    # specify the set of records to be "no students"
    formset = StudentFormset(query=Student.objects.none())
    context = { "formset": formset }
    return render("your_app/new.html", context)

  if request.method == "POST":
    # populate the formset with user input
    formset = StudentFormset(request.POST, request.FILES)

    if formset.is_valid():
      # save the entire formset
      formset.save()

      # make sure to redirect after a POST request
      return redirect("your_app:new")
Войти в полноэкранный режим

Выйти из полноэкранного режима

Если вам нужно указать внешний ключ в наборе форм, вам нужно перебирать каждую запись следующим образом:

# your_project/your_app/views/new.py

if formset.is_valid():
  # get the instances via the save method
  # but don't commit yet
  instances = formset.save(commit=False)
  for student in instances:
    student.school_id = 1
    # populate school_id and save one by one
    student.save()
Войти в полноэкранный режим

Выйти из полноэкранного режима

В этом случае может потребоваться «атомарная транзакция», когда все транзакции завершатся успешно или ни одна транзакция не будет успешной.

Вы можете использовать декоратор или with: block (см. документацию по последнему варианту; я предпочитаю декораторы с меньшим отступом).

# define a helper function with a decorator
from django.db import transaction

@transaction.atomic
def save_students_with_school(formset, school_id):
  instances = formset.save(commit=False)
  for student in instances:
    student.school_id = school_id
    # populate school_id and save one by one
    student.save()
Войти в полноэкранный режим

Выйти из полноэкранного режима

# call them in your view like this

if formset.is_valid():
  # call the atomic transaction
  save_students_with_school(formset, 1)
Войти в полноэкранный режим

Выйти из полноэкранного режима