Атрибут 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-классов для модели в административной панели