0

我正面临 django-tastypie 的一个非常奇怪的问题。好吧,这有点过于复杂,所以让我从我的应用程序的技术堆栈开始。

技术栈

  1. django -版本 1.4.1
  2. django-tastypie -版本 0.9.11
  3. angularjs -版本 1.0.4

问题

我有一个comment模型和两个用户模型StudentTeacher它们是从基用户模型的子类派生而来的。类似于以下内容。

## Base User
class BaseUser(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    # some more common fields here

## Teacher Model
class Teacher(BaseUser):
    college = models.ForeignKey(College)


## Student Model
class Student(BaseUser):
    Address = models.OneToOneField(Address)


## Comment Model
class Comment(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(backend.models.CustomUser)
    body = models.TextField()
    # Generic Relation with other models
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    user = generic.GenericForeignKey('content_type', 'object_id')

现在,正如您在我的comment模型中看到的那样,我使用GenericForeignKey了这样一个用户可以评论任何其他模型。

我在我的 sweetpie api.py 文件中定义了如下资源:

class TeacherResource(BaseModelResource):
    college = fields.ToOneField(CollegeResource, 'college', full=True)

    class Meta(BaseModelResource.Meta):
        queryset = models.Teacher.objects.all()
        resource_name = 'teacher'

    def dehydrate(self, bundle):
        # Add content type url
        ctype = models.ContentType.objects.get_for_model(models.Teacher)
        bundle.data['content_type_id'] = ctype.id
        bundle.data['content_type'] = '/api/v1/contrib/contenttype/%i' % ctype.id
        return bundle


class StudentResource(BaseModelResource):

    class Meta(BaseModelResource.Meta):
        queryset = models.Student.objects.all()
        resource_name = 'student'

    def dehydrate(self, bundle):
        # Add content type url
        ctype = models.ContentType.objects.get_for_model(\
                models.ProspectiveCandidate)
        bundle.data['content_type_id'] = ctype.id
        bundle.data['content_type'] = '/api/v1/contrib/contenttype/%i' % ctype.id
        return bundle


class CommentResource(BaseModelResource):
    custom_user = fields.ToOneField(CustomUserResource,
                                 'custom_user', full=True)
    user = fields.ToOneField(ContentTypeResource, 'content_type')

    class Meta(MarketingResource.Meta):
        queryset = models.Comment.objects.all()
        resource_name = 'comment'
        always_return_data = True
        filtering = {
            'user' : ALL_WITH_RELATIONS,
            'object_id': ALL_WITH_RELATIONS
        }

    def hydrate(self, bundle):
        print bundle.data
        bundle.obj.user = models.ContentType.objects.get_for_id(\
                int(bundle.data['object_id']))
        bundle.obj.object_id = int(bundle.data['object_id'])
        bundle.obj.employee = bundle.request.user.custom_user
        return bundle

    def dehydrate(self, bundle):
        if bundle.obj.date:
            bundle.data['date'] = timesince.timesince(bundle.obj.date)
        return bundle

以上所有资源均已正确注册。每个资源的GET方法都可以完美运行。我angularjs' $resource用来调用tastepie 的REST api。以下是我用来发送发布请求CommentResource以创建新的 commetn 对象的通用方法。

function make_comment(service, scope){
    service.save({
        "user": scope.user.content_type,
        "object_id": scope.user.id,
        "comments": $("textarea#comment").val()
    }, function(data){
        // Success callback Method
        scope.comments.push(data);
    }); 
}

很简单吧?现在在上述方法中,ascope.user可以是教师对象或学生对象,并且该方法只需使用该服务使用给定数据发出 POST 请求:

http://127.0.0.1:8000/api/v1/comment

问题是,当它scope.user是一个学生对象并且我调用上述方法时,我得到了201 created响应,但是当它是一个教师对象时,它给了我一个404 Not Found错误。

调试

  • 我已经确定传入的数据是正确的。
  • 我已确保教师对象存在。
  • 我已确保传入的内容类型正确。
  • 使用学生和教师对象时传入的数据非常相似(如下所示):

    对于传入的学生数据和响应是:

    数据 = {'user': '/api/v1/contrib/contenttype/15', 'object_id': '16', 'comments': 'sadfsadfsadfasdf'} 响应 = [19/Mar/2013 18:08:47] “POST /api/v1/comment HTTP/1.1”201 741

    对于传入的教师数据是:

    数据 = {'user': '/api/v1/contrib/contenttype/14', 'object_id': '62', 'comments': 'test comment'} 响应 = [19/Mar/2013 18:09:44 ] "POST /marketing/api/v1/comment HTTP/1.1" 404 3211

我无法理解为什么使用相同的代码适用于一种模型而不适用于另一种?你能给我一些指点吗?谢谢。

更新

所以我使用了一个自定义的 http 错误跟踪中间件,它会404 Not Found在我关闭它时发送响应,我现在收到以下错误。

ContentType 匹配查询不存在

我查找了数据库,id 为 14 的内容类型是教师,它在数据库中。

4

1 回答 1

0

问题在于水合物方法:

def hydrate(self, bundle):
    print bundle.data
    bundle.obj.user = models.ContentType.objects.get_for_id(\
            int(bundle.data['object_id'])) // this should be content_type_id
    bundle.obj.object_id = int(bundle.data['object_id'])
    bundle.obj.employee = bundle.request.user.custom_user
    return bundle

因此更改了注释功能以传入content_type_id并将水合物方法更改为

def hydrate(self, bundle):
    print bundle.data
    bundle.obj.user = models.ContentType.objects.get_for_id(\
            int(bundle.data['content_type_id'])) // this was friggin stupid.
    bundle.obj.object_id = int(bundle.data['object_id'])
    bundle.obj.employee = bundle.request.user.custom_user
    return bundle
于 2013-03-19T13:50:49.747 回答