Как получить связанный дочерний тип, если родитель может иметь несколько дочерних типов? - PullRequest
0 голосов
/ 19 мая 2019

Допустим, у меня есть 3 модели, подобные этой:

class Parent(models.model):
    CHILD_CHOICES = (
        ('ChildA', 'Child A'),
        ('ChildB', 'Child B'),
    )
    name = models.CharField(max_length=50)
    child_type = models.CharField(choices=CHILD_CHOICES, max_length=25, blank=True)

class ChildA(models.model):
    parent = OneToOneField('Parent',related_name='child_a',blank=True, null=True)

class ChildB(models.model):
    parent = OneToOneField('Parent',related_name='child_b',blank=True, null=True)

Когда создается родитель, создается связанная дочерняя модель (в зависимости от поля child_type).

Как получитьв соответствии с типом Child от Parent в представлении Parent, чтобы сопоставить пользовательскую форму нужному дочернему элементу?(для редактирования родительского и правильного дочернего типа в одном представлении)

(в моем реальном сценарии у меня есть 10 различных дочерних типов)

1 Ответ

1 голос
/ 19 мая 2019

На ум приходят два варианта.

1) Вы можете использовать метод get_model (), который, вероятно, чище, чтобы найти правильного потомка.

2) Вы можете сделать оператор IF в середине набора запросов. Я жестко запрограммировал пример, но вы, вероятно, можете использовать переменную child_type до конца и использовать annotate. Я просто показываю пример того, как вы можете разбить и настроить ваши запросы с помощью нескольких связанных моделей.

Пример 1:

from django.db.models import get_model

class ParentForm(forms.Form):   # or view
    ***code here**

    parent_model = Parent.objects.get(pk=1)

    # Get model name from CHILD_CHOICES.
    child_relation = [k for k, v in Parent.CHILD_CHOICES if v == parent_model.child_type]

    child_model = get_model('app_name', child_relation)
    child_model.objects.all()

    ***more code here***

Пример 2: (иногда удобно в зависимости от настроек):

class ParentManager(models.Manager):
    def get_child_info(self, child_type):
        try:
            query = super(ParentManager, self).get_queryset()

            # This line only works if the models have the same fields, otherwise do the below.
            query = query.values('id', 'name')

            if child_type == 'Child A':
                # Do this if your child models have different fields.
                query = query.values('id', 'name', 'unique_childA_field')
                query = query.select_related('child_a').all()
            elif child_type == 'Child B':
                # Do this if your child models have different fields.
                query = query.values('id', 'name', 'unique_childB_field')
                query = query.select_related('child_b').all()
        except Exception:
            query = None

    return query

class Parent(models.model):
    CHILD_CHOICES = (
        ('ChildA', 'Child A'),
        ('ChildB', 'Child B'),
    )
    name = models.CharField(max_lenght=50)
    child_type = models.CharField(choices=CHILD_CHOICES, max_length=25, blank=True)

    objects = ParentManager()

тогда по вашему мнению или форме:

class ParentForm(forms.Form):   # or view
    ***code here**

    child_info = Parent.objects.get_child_info('Child A')

    ***more code here***
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...