РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
431 of 818 menu

Поле ModelChoiceField

Поле ModelChoiceField предназначено для создания выпадающего списка, где каждый вариант представляет собой объект модели. Оно принимает аргумент queryset - набор объектов, из которых пользователь может выбрать один. Это поле автоматически валидирует переданные данные, проверяя наличие выбранного объекта в указанном наборе запросов. При отправке формы значение поля преобразуется в объект модели, а не в его первичный ключ.

Синтаксис

from django import forms from .models import Category class MyForm(forms.Form): category = forms.ModelChoiceField(queryset=Category.objects.all())

Параметры

Основной параметр - queryset, задающий набор объектов для выбора. Дополнительные параметры включают empty_label для добавления пустого пункта, to_field_name для указания поля модели, используемого в качестве значения, и стандартные параметры полей форм (например, required, initial, label).

Пример . Использование в форме

Создадим форму для выбора категории статьи с помощью ModelChoiceField:

from django import forms from .models import Category, Article class ArticleForm(forms.Form): title = forms.CharField(max_length=100) content = forms.CharField(widget=forms.Textarea) category = forms.ModelChoiceField(queryset=Category.objects.all())

При рендеринге форма создаст выпадающий список со всеми категориями из базы данных. После отправки формы значение поля category будет объектом модели Category, а не его ID.

Пример . Обработка данных

Рассмотрим обработку данных из формы с ModelChoiceField в представлении:

from django.shortcuts import render from .forms import ArticleForm def create_article(request): if request.method == 'POST': form = ArticleForm(request.POST) if form.is_valid(): title = form.cleaned_data['title'] content = form.cleaned_data['content'] category = form.cleaned_data['category'] # category - объект Category print(f"Title: {title}") print(f"Category: {category.name}") else: form = ArticleForm() return render(request, 'create_article.html', {'form': form})

Валидация поля выполняется автоматически: если выбранный объект не существует в queryset, будет вызвана ошибка валидации.

Фильтрация queryset

Используйте метод filter, чтобы динамически ограничивать набор доступных объектов:

from django import forms from .models import Article, Category class ArticleForm(forms.Form): title = forms.CharField(max_length=100) category = forms.ModelChoiceField( queryset=Category.objects.filter(is_active=True) )

В этом примере в выпадающем списке отобразятся только активные категории.

Пустой пункт в выпадающем списке

Используйте параметр empty_label для добавления пустого пункта:

from django import forms from .models import Category class CategoryForm(forms.Form): category = forms.ModelChoiceField( queryset=Category.objects.all(), empty_label="Выберите категорию" )

Если установить empty_label в None, пустой пункт не будет отображаться. При значении required=False выбор пустого пункта допустим, и поле вернет None.

Использование to_field_name

Параметр to_field_name позволяет указать поле модели, которое будет использоваться в качестве значения выпадающего списка:

from django import forms from .models import Article class ArticleForm(forms.Form): article = forms.ModelChoiceField( queryset=Article.objects.all(), to_field_name="slug" )

Теперь значениями в выпадающем списке будут не первичные ключи, а значения поля slug модели Article.

Динамическая настройка queryset

Для динамической фильтрации queryset в зависимости от пользователя или других условий переопределите метод __init__ формы:

from django import forms from .models import Category class ArticleForm(forms.Form): title = forms.CharField(max_length=100) category = forms.ModelChoiceField(queryset=Category.objects.all()) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['category'].queryset = Category.objects.filter( author=user )

В этом случае доступные категории будут зависеть от переданного пользователя.

Результат валидации

Если пользователь выберет несуществующий объект, поле вызовет ошибку ValidationError. Форма будет содержать ошибку в поле category:

from django import forms from .models import Category form = CategoryForm({'category': 999}) # Несуществующий ID if not form.is_valid(): print(form.errors['category'])

Результат выполнения кода:

"Select a valid choice. 999 is not one of the available choices."

Смотрите также

  • класс Form,
    основной класс для создания форм
  • класс ModelForm,
    форма, связанная с моделью базы данных
  • поле ChoiceField,
    выбор из фиксированного списка вариантов
  • поле ModelMultipleChoiceField,
    выбор нескольких объектов модели
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить