Как иметь разные models.ForeignKey related_name для каждого связанного объекта одной и той же модели?

Я работаю с Django Rest, чтобы иметь несколько объектов "текстовых блоков", связанных с объектом документа. Пока что я добился этого с помощью простой функции models.ForeignKey.

Однако я отображаю все эти текстовые блоки в нескольких колонках во фронт-энде. Модель текстового блока будет иметь поле колонки, чтобы определить, что идет в какую колонку. Поскольку порядок этих текстовых блоков имеет значение, я боялся, что все они будут смешаны в одном поле "all_columns". Пока что я решил, что самый простой способ - это позволить DRF возвращать что-то вроде следующего:

{
    "name": "Comparing Two Characters",
    "column_A": [
        {
            "title": "Text Block",
            "body": "lorem ipsum blah blah"
            "col": 1
        }
    ],
    "column_B": [
        {
            "title": "Text Block 2",
            "body": "lorem ipsum blah blah"
            "col": 2
        },
            {
            "title": "Text Block 3",
            "body": "lorem ipsum blah blah"
            "col": 2
        }
    ]
}

Как бы я мог реализовать нечто подобное? Я не уверен, что использование связанных полей вообще идеально подходит для таких случаев. Буду благодарен за любую помощь!

Вот мой текущий код models.py для справки:

class Document(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)
    # other fields
    def __str__(self):
            return self.name

class TextBlock(models.Model):
    id = models.AutoField(primary_key=True)
    document = models.ForeignKey(Document, related_name='blocks', on_delete=models.CASCADE)
    col = models.CharField(max_length=100)
    title = models.CharField(max_length=100)
    body = models.CharField(max_length=100)

Попробуйте это:

from collections import defaultdict

class Document(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)
    # other fields
    def __str__(self):
            return self.name

    def blocks_by_column(self):
        block_group = defaultdict(list)
        for block in self.blocks.all():
            block_group[block.col].append(block)
        return block_group


class TextBlock(models.Model):
    id = models.AutoField(primary_key=True)
    document = models.ForeignKey(Document, related_name='blocks', on_delete=models.CASCADE)
    col = models.IntegerField()
    title = models.CharField(max_length=100)
    body = models.CharField(max_length=100)

Если у вас есть механизм упорядочивания, т.е. колонка порядка, вы можете изменить self.blocks.all() на self.blocks.order_by(<column>).all(). В дальнейшем вы можете изменить ключи blocks_group по своему усмотрению. 1 -> column_A.

Вернуться на верх