Атрибут fk_name
Атрибут fk_name используется в классе TabularInline для явного указания внешнего ключа, который связывает дочернюю модель с родительской. Это необходимо в тех случаях, когда между моделями существует несколько внешних ключей, и Django не может автоматически определить, по какому из них следует строить связь. Атрибут принимает строковое значение - имя поля модели, которое является внешним ключом.
Синтаксис
class ChildInline(admin.TabularInline):
model = ChildModel
fk_name = 'foreign_key_field_name'
Пример . С несколькими внешними ключами
Рассмотрим ситуацию, когда модель статьи имеет два внешних ключа на модель пользователя - автор и редактор. В этом случае необходимо указать fk_name для правильного отображения встроенной формы:
from django.db import models
from django.contrib import admin
class User(models.Model):
name = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='authored_articles'
)
editor = models.ForeignKey(
User,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='edited_articles'
)
class ArticleInline(admin.TabularInline):
model = Article
fk_name = 'author'
extra = 1
В этом примере атрибут fk_name установлен в 'author', что указывает Django на то, что встроенная форма должна использовать поле author для связи с родительской моделью пользователя.
Пример . С дополнительной фильтрацией
Атрибут fk_name также полезен, когда нужно использовать его в сочетании с методами, такими как get_queryset, для фильтрации объектов в inline форме по указанному внешнему ключу:
from django.contrib import admin
from myapp.models import User, Article
class ArticleInline(admin.TabularInline):
model = Article
fk_name = 'author'
extra = 2
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.filter(title__icontains='django')
Результат выполнения кода:
[<Article: Django for beginners>, <Article: Django advanced>]
Пример . С использованием в административной панели
Рассмотрим полный пример регистрации модели в административной панели с использованием fk_name для правильной связи между моделями:
from django.contrib import admin
from myapp.models import User, Article
class ArticleInline(admin.TabularInline):
model = Article
fk_name = 'editor'
extra = 1
fields = ('title', 'author')
class UserAdmin(admin.ModelAdmin):
inlines = [ArticleInline]
list_display = ('name',)
admin.site.register(User, UserAdmin)
Теперь при редактировании пользователя в административной панели будут отображаться статьи, где он указан как редактор, благодаря атрибуту fk_name, установленному в 'editor'.
Смотрите также
-
атрибут
model,
который определяет модель для встроенной формы -
атрибут
extra,
который задает количество пустых форм для добавления -
класс
TabularInline,
который используется для встроенного отображения связанных объектов в табличном формате -
атрибут
inlines,
который подключает встроенные классы к административной модели