Tastypie从继承的模型访问字段

时间:2012-10-05 19:49:37

标签: django tastypie

是否可以使用tastypie在相关模型中包含字段?

根据我的模型如下:如果我将一个VideoContent和一个TextContent实例保存到数据库,那么我可以从我的内容资源中获取2个对象,但是没有其他字段可用。

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

目标是能够使用更多ContentTypes扩展它,而无需更改内容资源(假设它可以在第一时间使其工作)

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 个答案:

答案 0 :(得分: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并且必须是tastypie提供的更好/更清洁的方式 - 他们不能期望你必须做这种类型的在这些类型的情况下手动重新包装 - 但是,也许他们这样做。我在这一点上只有大约8小时的tastypie经验,所以如果我解释这一切都错了,也许一些不错的stackoverflow用户可以让我直截了当。 :D:D:D

答案 1 :(得分:0)

我有同样的要求,最后解决了。

我不喜欢上面链接中给出的答案,因为我不喜欢将queryset和re-sorting结合起来的想法。

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

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