0

私はdjango-tastypieで本当に奇妙な問題に直面しています。さて、これは少し複雑すぎるので、アプリケーションの技術スタックから始めましょう。

技術スタック

  1. ジャンゴ-バージョン 1.4.1
  2. django-tastypie -バージョン 0.9.11
  3. angularjs-バージョン1.0.4

問題

commentモデルと 2 つのユーザー モデルがStudentあり、Teacherこれらは基本ユーザー モデルのサブクラス化から派生しています。次のようなもの。

## 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以下は、新しいコメント オブジェクトを作成するためにポスト リクエストを送信するために使用する一般的なメソッドです。

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.usera は教師オブジェクトまたは生徒オブジェクトのいずれかになり、メソッドは単にサービスを使用して、指定されたデータで POST 要求を作成し、次のことを行います。

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

問題はscope.user、学生オブジェクトで上記のメソッドを呼び出すと201 created応答が返されるが、教師オブジェクトの場合は404 Not Foundエラーが発生することです。

デバッグ

  • 渡されたデータが正しいことを確認しました。
  • 教師オブジェクトが存在することを確認しました。
  • contenttype が正しく渡されたことを確認しました。
  • 生徒オブジェクトと教師オブジェクトを使用する際に渡されるデータは非常に似ています (次のようになります)。

    渡された学生データの場合、応答は次のとおりです。

    data = {'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

    渡された教師のデータは次のとおりです。

    data = {'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 の contenttype は Teacher であり、データベース内にあります。

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 に答える