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()