Tastypie доступ к полям из унаследованных моделей

Можно ли включить поля на родственные модели, используя вкусный пирог?

В соответствии с моими моделями ниже: если я сохраню один экземпляр VideoContent и один экземпляр TextContent в БД, я могу затем вернуть 2 объекта из моего ресурса Content, однако ни одно из дополнительных полей недоступно.

Можно ли включить поля из связанных моделей (в данном случае, URL-адреса видео и текстового контента), и будет ли это способствовать добавлению новых типов контента в будущем без необходимости перезаписывать ресурс контента, или я пришел к этому из неправильное направление?

Цель состоит в том, чтобы иметь возможность расширить это с помощью большего количества ContentTypes без необходимости вносить изменения в ресурс Content (при условии, что это возможно, чтобы он работал в первую очередь)

Models.py:

class Content(models.Model):
    parent = models.ForeignKey('Content', related_name='children', null=True, blank=True)

class TextContent(Content):
    text = models.CharField(max_length=100)

class VideoContent(Content):
    url = models.CharField(max_length=1000)

И тогда мои ресурсы:

class ContentResource(ModelResource):
    children = fields.ToManyField('myapp.api.resources.ContentResource', 'children', null=True, full=True)

    class Meta:
        resource_name = 'content'
        queryset = ContentResource.objects.all()
        authorization = Authorization()
        always_return_data = True

2 ответа

Решение

Я нашел хорошее решение в другом ответе

Заполнение ресурса вкусных пирогов для модели Django с наследованием нескольких таблиц


Я столкнулся с той же проблемой - хотя я все еще в процессе ее решения. Две вещи, которые я понял до сих пор:

django-model-utils предоставляет менеджер наследования, который позволяет вам использовать абстрактный базовый класс для запроса его таблицы и может автоматически понижать результаты запроса.

Стоит обратить внимание на методы дегидратации / регидратации, доступные для классов ресурсов.

Вот что я сделал:

class CommandResource(ModelResource):

   class Meta:
        queryset = Command.objects.select_subclasses().all()

Это только дает вам половину пути - ресурс также должен включать в себя материал для дегидратации / регидратации, потому что вы должны вручную упаковать объект для передачи (или получения) от пользователя.

Теперь я осознаю, что это супер-хакерство, и есть вкусный способ, который обеспечивает вкусный пирог - они не могут ожидать, что вам придется делать такой тип ручной переупаковки в подобных ситуациях - но, возможно, они делают. У меня есть только около 8 часов опыта с tastypie @ в этот момент, так что, если я все это объясняю неправильно, возможно, какой-нибудь хороший пользователь stackru сможет исправить меня.:D:D:D

У меня было такое же требование, и я, наконец, решил его.

Мне не понравился ответ, приведенный в приведенной выше ссылке, потому что мне не понравилась идея объединения набора запросов и повторной сортировки.

Видимо, вы можете наследовать несколько ресурсов.

Подклассируя несколько ресурсов, вы включаете поля ресурсов.
И поскольку эти поля уникальны для каждого ресурса, я сделал их обнуляемыми в init.

Интересно, есть ли способ перечислить родителей только один раз. (Теперь их два. Один для подклассов, а второй в мета)

class SudaThreadResource(ThreadResource):

    def __init__(self, *args, **kwargs):
        super(SudaThreadResource, self).__init__(*args, **kwargs)

        for field_name, field_object in self.fields.items():
            # inherited_fields  can be null                                                                                                                                                                                                                                     
            if field_name in self.Meta.inherited_fields:
                field_object.null=True

    class Meta(ThreadResource.Meta):
        resource_name = 'thread_suda'
        usedgoodthread_fields = UsedgoodThreadResource.Meta.fields[:]
        userdiscountinfothread_fields = UserDiscountinfoThreadResource.Meta.fields[:]
        staffdiscountinfothread_fields = StaffDiscountinfoThreadResource.Meta.fields[:]
        bitem_checklistthread_fields = BitemChecklistThreadResource.Meta.fields[:]

        parent_field_set = set(ThreadResource.Meta.fields[:])

        field_set = set(
            set(usedgoodthread_fields) |
            set(userdiscountinfothread_fields) |
            set(staffdiscountinfothread_fields) |
            set(bitem_checklistthread_fields)
        )

        fields = list(field_set)
        inherited_fields = list(field_set - parent_field_set)


        queryset = forum_models.Thread.objects.not_deleted().exclude(
            thread_type__in=(forum_const.THREAD_TYPE_MOMSDIARY, forum_const.THREAD_TYPE_SOCIAL_DISCOUNTINFO)
        ).select_subclasses()
Другие вопросы по тегам