Перечень объектов модели1, связанных с той же моделью2, что и модель3.

Вопрос или проблема

проблема

У меня есть две модели (ModelB, ModelC), связанные с другой (ModelA). Я хочу показать все объекты ModelC, связанные с тем же объектом ModelA, что и ModelB, на странице администратора ModelB.

модели

class ModelA(models.Model):
    # ...


class ModelB(models.Model):
    # ...
    model_a = models.OneToOneField(ModelA)


class ModelC(models.Model):
    # ...
    models_a = models.ManyToManyField(ModelA)

админ

class ModelCInline(admin.StackedInline):
    model = ModelC

class ModelBAdmin(admin.ModelAdmin):
    inlines = (ModelCInline,)
    # ...

Я экспериментировал с инлайнами, но так и не нашел решения.

Ответ или решение

Для решения вашей задачи по отображению всех объектов ModelC, связанных с тем же объектом ModelA, что и объект ModelB, на странице администратора ModelB, необходимо внести некоторые изменения в ваш код.

Во-первых, связки между моделями в ваших классах установлены следующим образом: ModelB имеет однонаправленное отношение OneToOne к ModelA, а ModelC имеет двунаправленное отношение ManyToMany к ModelA. Это значит, что для объекта ModelB вы можете получить связанный объект ModelA, а затем на его основе извлечь все соответствующие объекты ModelC.

Вот как вы можете это сделать:

Модели

Убедитесь, что ваши модели выглядят как в вашем примере:

from django.db import models

class ModelA(models.Model):
    # Поля вашей модели ModelA
    pass

class ModelB(models.Model):
    model_a = models.OneToOneField(ModelA, on_delete=models.CASCADE)

class ModelC(models.Model):
    models_a = models.ManyToManyField(ModelA)

Админская часть

Вам нужно создать ModelCInline, который будет фильтровать объекты ModelC по связанному ModelA для текущего объекта ModelB.

from django.contrib import admin
from .models import ModelB, ModelC, ModelA

class ModelCInline(admin.TabularInline):  # Вы можете использовать StackedInline, если нужно
    model = ModelC
    extra = 0

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        # Получаем объект ModelA, связанный с текущим объектом ModelB
        model_b_id = request.resolver_match.kwargs.get('object_id')
        try:
            model_b = ModelB.objects.get(id=model_b_id)
            return qs.filter(models_a=model_b.model_a)
        except ModelB.DoesNotExist:
            return qs.none()  # Если объект ModelB не найден, возвратите пустой QuerySet

class ModelBAdmin(admin.ModelAdmin):
    inlines = (ModelCInline,)
    # Другие настройки вашего ModelBAdmin

admin.site.register(ModelB, ModelBAdmin)
admin.site.register(ModelC)  # Регистрируем ModelC, если еще не зарегистрирована
admin.site.register(ModelA)  # Регистрируем ModelA, если еще не зарегистрирована

Объяснение кода

  1. ModelCInline:

    • Мы переопределяем метод get_queryset, чтобы вернуть только те объекты ModelC, которые связаны с объектом ModelA, на который ссылается текущий объект ModelB.
    • Если объект ModelB не найден, метод возвращает пустой QuerySet, чтобы избежать ошибок.
  2. ModelBAdmin:

    • Включает ModelCInline для отображения связанных объектов ModelC.

Теперь, когда вы зайдете в интерфейс администратора для ModelB, вы увидите все связанные объекты ModelC, которые имеют ту же связь с ModelA, что и текущий ModelB.

Это решение должно полностью удовлетворить ваши требования. Если у вас есть дополнительные вопросы или требуется дальнейшая помощь, пожалуйста, дайте знать!

Оцените материал
Добавить комментарий

Капча загружается...