Атрибут fk_name

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

Синтаксис

pythonclass ChildInline(admin.TabularInline):
  model = ChildModel
  fk_name = 'foreign_key_field_name'

Пример . С несколькими внешними ключами

Рассмотрим ситуацию, когда модель статьи имеет два внешних ключа на модель пользователя - автор и редактор. В этом случае необходимо указать fk_name для правильного отображения встроенной формы:

pythonfrom 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 форме по указанному внешнему ключу:

pythonfrom 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')

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

python[<Article: Django for beginners>, <Article: Django advanced>]

Пример . С использованием в административной панели

Рассмотрим полный пример регистрации модели в административной панели с использованием fk_name для правильной связи между моделями:

pythonfrom 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,
    который подключает встроенные классы к административной модели