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

Атрибут fk_name

Атрибут fk_name класса StackedInline указывает, какое именно поле внешнего ключа следует использовать, если между родительской и дочерней моделями существует более одной связи. Этот атрибут обязателен, когда модель содержит несколько внешних ключей на одну и ту же модель.

Синтаксис

class MyInline(StackedInline): model = ChildModel fk_name = 'field_name'

Пример

Рассмотрим модели, где статья имеет автора и редактора, оба являются пользователями:

from django.db import models from django.contrib.auth.models import User class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='authored_articles') editor = models.ForeignKey(User, on_delete=models.CASCADE, related_name='edited_articles') created_at = models.DateTimeField(auto_now_add=True)

В административной панели мы хотим редактировать статьи пользователя, но Django не знает, какое поле внешнего ключа использовать:

from django.contrib import admin from myapp.models import Article, User class ArticleInline(StackedInline): model = Article # Django не может определить, какое поле ForeignKey использовать @admin.register(User) class UserAdmin(admin.ModelAdmin): inlines = [ArticleInline]

Чтобы решить эту проблему, укажем fk_name:

from django.contrib import admin from myapp.models import Article, User class ArticleInline(StackedInline): model = Article fk_name = 'author' # Явно указываем, что используем поле author @admin.register(User) class UserAdmin(admin.ModelAdmin): inlines = [ArticleInline]

Пример

Теперь создадим административный интерфейс для модели 'Category', где используются два внешних ключа на модель 'Product':

from django.db import models class Product(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) class Category(models.Model): name = models.CharField(max_length=100) main_product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True, related_name='main_categories') secondary_product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True, related_name='secondary_categories')

Создадим inline для редактирования категорий внутри продукта:

from django.contrib import admin from myapp.models import Product, Category class CategoryInline(StackedInline): model = Category fk_name = 'main_product' extra = 1 @admin.register(Product) class ProductAdmin(admin.ModelAdmin): list_display = ('name', 'price') inlines = [CategoryInline]

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

# Результат: в админке продукта отображаются категории, # где main_product_id равен id текущего продукта

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

  • класс StackedInline,
    который используется для создания вертикальных inline-форм в административной панели
  • класс TabularInline,
    который создает горизонтальные inline-формы для отображения связанных объектов
  • атрибут model,
    который указывает модель для inline-редактирования
  • атрибут inlines,
    который определяет набор inline-классов для модели в административной панели
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить