在tastypie资源的POST方法中找不到404

时间:2013-03-19 13:28:18

标签: django angularjs tastypie

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

Tech Stack

  1. django - 版本1.4.1
  2. django-tastypie - 版本0.9.11
  3. angularjs - 版本1.0.4
  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,以便用户可以对任何其他模型发表评论。

    我在tastypie 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来调用tastypie的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);
        }); 
    }
    
    很简单呃?现在在上面的方法中,scope.user可以是教师对象或学生对象,并且该方法只是使用该服务来发出具有给定数据的POST请求:

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

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

    调试

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

      传入的学生数据

      ,响应为:

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

      传入的教师数据

      是:

      data = {'user':'/ api / v1 / contrib / contenttype / 14','object_id':'62','comments':'test comment'} response = [19 / Mar / 2013 18:09:44]“POST / marketing / api / v1 / comment HTTP / 1.1”404 3211

    我无法理解为什么使用相同的代码可以用于一个模型而不用于另一个模型?能不能给我一些指示。感谢。

    更新

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

      

    ContentType匹配查询不存在

    我查了一下数据库,id为14的contenttype是教师,它就在数据库中。

1 个答案:

答案 0 :(得分: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