私はdjango-tastypieで本当に奇妙な問題に直面しています。さて、これは少し複雑すぎるので、アプリケーションの技術スタックから始めましょう。
技術スタック
- ジャンゴ-バージョン 1.4.1
- django-tastypie -バージョン 0.9.11
- 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.user
a は教師オブジェクトまたは生徒オブジェクトのいずれかになり、メソッドは単にサービスを使用して、指定されたデータで 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 であり、データベース内にあります。