【问题标题】:django-tastypie: linking a ModelResource to a Resourcedjango-tastypie:将 ModelResource 链接到资源
【发布时间】:2011-12-02 02:45:13
【问题描述】:

我目前正在尝试 django-tastypie 来设计一个 RESTful api。我遇到了一个问题:

# the RevisionObject retrieve commits info through pysvn
# This Resource is fully functionnal (RevisionObject code is not here)
class RevisionResource(Resource):
    id = fields.CharField(attribute='revision')
    description = fields.CharField(attribute='message')
    author = fields.CharField(attribute='author')
    changed_path = fields.ListField(attribute='changed_paths')

    class Meta:
        object_class = RevisionObject
        allowed_methods = ['get']
        resource_name = 'revision'

class RevisionToApplyResource(ModelResource):
    #### here's the problem
    revision = fields.ToManyField(RevisionResource, 'revision')
    ####
    class Meta:
        queryset = RevisionToApply.objects.all()

在我的 models.py 中有:

class RevisionToApply(models.Model):
    patch = models.ForeignKey(PatchRequest)
    revision = models.PositiveIntegerField()
    applied = models.BooleanField(default = False)

我的问题是 RevisionToApply 模型(用于 django)对修订使用了 int。

如何告诉tastepie 使用RevisionToApplyResource 的修订字段作为指向RevisionResource 的指针?如果 ToXxxxField 仅用于与 django 模型链接,那么插入 ResourceObject 的最佳时机是什么?

谢谢。

class NoForeignKeyToOneField(ToOneField):
    def dehydrate(self, bundle):
        try:
            obj_key = getattr(bundle.obj, self.attribute)
            foreign_obj = self.to_class().obj_get(pk=obj_key)
        except ObjectDoesNotExist:
            foreign_obj= None

        if not foreign_obj:
            if not self.null:
                raise ApiFieldError("The model '%r' has an empty attribute"
                   "'%s' and doesn't allow null value." % (bundle.obj,
                   self.attribute))
            return None

        self.fk_resource = self.get_related_resource(foreign_obj)
        fk_bundle = Bundle(obj=foreign_obj, request=bundle.request)
        return self.dehydrate_related(fk_bundle, self.fk_resource)

【问题讨论】:

    标签: django django-models tastypie


    【解决方案1】:

    我会这样做。看看ToOneField 类是如何工作的,您会注意到 hydrate/dehydrate 方法对负责获取和设置实际的相关实例。通过继承 ToOneField 并覆盖这两个方法,您可以获得 Tastypie 的自动资源处理的好处,而无需实际的外键。

    (我指的是ToOneField 而不是ToManyField,因为在您的模型中,给定的RevisionToApply 似乎只能指向一个修订版。)

    看起来像这样:

    class NoForeignKeyToOneField(ToOneField):
    
        def dehydrate(self, bundle):
            # Look up the related object manually
            try:
                obj_key = getattr(bundle.obj, self.attribute)
                ###
                # Get the revision object here. If you want to make it generic,
                # maybe pass a callable on __init__ that can be invoked here
                ###
                foreign_obj = revision_object
            except ObjectDoesNotExist:
                foreign_obj = None
            # The rest remains the same
            if not foreign_obj:
                if not self.null:
                    raise ApiFieldError("The model '%r' has an empty attribute '%s' and doesn't allow a null value." % (bundle.obj, self.attribute))
                return None
    
            self.fk_resource = self.get_related_resource(foreign_obj)
            fk_bundle = Bundle(obj=foreign_obj, request=bundle.request)
            return self.dehydrate_related(fk_bundle, self.fk_resource)
    
        def hydrate(self, bundle):
            value = super(NoForeignKeyToOneField, self).hydrate(bundle)
    
            if value is None:
                return value
    
            # Here, don't return the full resource, only the primary key
            related_resource = self.build_related_resource(value, request=bundle.request)
            return related_resource.pk
    

    然后在你的资源中使用这个字段类型而不是基本的ToOneField。我还没有测试过,但我相信这种方法是合理的、简单的,并且可以完成工作。

    【讨论】:

    • 它适用于脱水方法。感谢您的小费。我仍然无法使用水合物。
    猜你喜欢
    • 2023-03-28
    • 2012-10-15
    • 1970-01-01
    • 2012-07-21
    • 2016-06-24
    • 2012-08-17
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    相关资源
    最近更新 更多