Tastypie 从继承的模型中访问字段

Posted

技术标签:

【中文标题】Tastypie 从继承的模型中访问字段【英文标题】:Tastypie accessing fields from inherited models 【发布时间】:2012-09-27 00:21:24 【问题描述】:

是否可以在相关模型上包含字段,使用 sweetpie?

根据我的以下模型:如果我将一个 VideoContent 和一个 TextContent 实例持久化到数据库,然后我可以从我的 Content 资源中取回 2 个对象,但是没有其他字段可用。

是否可以包含来自相关模型的字段(在本例中为视频 url 和文本内容),是否可以满足将来添加更多内容类型的需求,而无需重写内容资源,或者我来了这是从错误的方向吗?

我们的目标是能够使用更多的 ContentType 来扩展它,而不必对 Content 资源进行更改(假设可以首先让它工作)

模型.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

【问题讨论】:

【参考方案1】:

我也有同样的需求,终于解决了。

我不喜欢上面链接中给出的答案,因为我不喜欢结合查询集和重新排序的想法。

显然,您可以继承多个资源。

通过对多个资源进行子类化,您可以包含资源的字段。 由于这些字段对于每个资源都是唯一的,因此我在 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()

【讨论】:

【参考方案2】:

我在另一个答案中找到了一个很好的解决方案

Populating a tastypie resource for a multi-table inheritance Django model


我遇到了同样的问题 - 尽管我仍在解决它。到目前为止,我已经弄清楚了两件事:

django-model-utils 提供了一个继承管理器,让您可以使用抽象基类来查询它的表,并且可以自动向下转换查询结果。

需要注意的一点是资源类可用的 dehydrate/rehydrate 方法。

这就是我所做的:

class CommandResource(ModelResource):

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

这只会让您成功 - 资源还必须包含脱水/再水合的东西,因为您必须手动将对象打包以从用户那里传输(或接收)。

我现在意识到的是,这是超级 hacky 并且必须有一个更好/更清洁的方式由美味派提供 - 他们不能指望你必须在这些类型的情况下进行这种类型的手动重新打包 -但是,也许他们会。我在这点上只有大约 8 小时的美味派经验,所以如果我解释这一切都错了,也许一些好的 *** 用户可以让我直截了当。 :D :D :D

【讨论】:

以上是关于Tastypie 从继承的模型中访问字段的主要内容,如果未能解决你的问题,请参考以下文章

使用 TastyPie 过滤不同的字段

无法从超类访问 Django 模型的子类

访问资源时 jQuery Ajax 失败 (Django Tastypie)

从继承的受保护的 Java 字段创建公共访问器

如何从车把模板访问主干模型的计算字段?

如何从车把模板访问主干模型的计算字段?