Python 2个以上型号的Tastype关系字段
我正在学习为Django项目使用tastypie编写API。我在models.py中有以下代码: 我在api.py中有以下代码: 当我发送一个POST请求到http://127.0.0.1:8000/api/v1/auth i、 e: 然后成功创建一个用户和一个UserProfile对象。但我还想在同一端点中创建UserDeviceID对象。我尝试了不同的组合,但无法创建UserDeviceID对象。有人能用一些示例代码详细介绍一下Tastypie关系字段,让我了解关系在Django中是如何工作的吗 例如,我在api.py中编辑了我的CreateUserProfileResource,并添加了以下行:Python 2个以上型号的Tastype关系字段,python,django,python-3.x,tastypie,Python,Django,Python 3.x,Tastypie,我正在学习为Django项目使用tastypie编写API。我在models.py中有以下代码: 我在api.py中有以下代码: 当我发送一个POST请求到http://127.0.0.1:8000/api/v1/auth i、 e: 然后成功创建一个用户和一个UserProfile对象。但我还想在同一端点中创建UserDeviceID对象。我尝试了不同的组合,但无法创建UserDeviceID对象。有人能用一些示例代码详细介绍一下Tastypie关系字段,让我了解关系在Django中是如何工作
deviceid = fields.ForeignKey('users.api.CreateUserDeviceIdsResource', 'deviceid', full=True)
因此CreateUserProfileResource现在看起来像:
class CreateUserProfileResource(ModelResource):
user = fields.ForeignKey('users.api.CreateUserResource', 'user', full=True)
deviceid = fields.ForeignKey('users.api.CreateUserDeviceIdsResource', 'deviceid', full=True)
class Meta:
list_allowed_methods = ['get','post']
...
...
并为UserDeviceID模型添加了新资源:
当我尝试发送POST请求时:
curl -X POST -H "Content-Type: application/json" -d '{"user": {"email":"a@b.com","username":"abcdef"}, "referral_code":"abc123", "deviceid": {"device_id": "abc"}}' http://127.0.0.1:8000/api/v1/auth
我得到以下错误回溯:
{"error_message": "null value in column \"user_id\" violates not-null constraint
DETAIL: Failing row contains (2, abc, def, ghi, null).
", "traceback": "Traceback (most recent call last):
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/backends/utils.py\", line 65, in execute
return self.cursor.execute(sql, params)
psycopg2.IntegrityError: null value in column \"user_id\" violates not-null constraint
DETAIL: Failing row contains (2, abc, def, ghi, null).
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 201, in wrapper
response = callback(request, *args, **kwargs)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 432, in dispatch_list
return self.dispatch('list', request, **kwargs)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 464, in dispatch
response = method(request, **kwargs)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 1340, in post_list
updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 2104, in obj_create
return self.save(bundle)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 2247, in save
self.save_related(bundle)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 2318, in save_related
related_resource.save(related_bundle)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 2250, in save
bundle.obj.save()
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/base.py\", line 589, in save
force_update=force_update, update_fields=update_fields)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/base.py\", line 617, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/base.py\", line 698, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/base.py\", line 731, in _do_insert
using=using, raw=raw)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/manager.py\", line 92, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/query.py\", line 921, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/sql/compiler.py\", line 920, in execute_sql
cursor.execute(sql, params)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/backends/utils.py\", line 81, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/backends/utils.py\", line 65, in execute
return self.cursor.execute(sql, params)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/utils.py\", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File \"/vagrant/venv/lib/python3.4/site-packages/django/utils/six.py\", line 658, in reraise
raise value.with_traceback(tb)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/backends/utils.py\", line 65, in execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: null value in column \"user_id\" violates not-null constraint
DETAIL: Failing row contains (2, abc, def, ghi, null).
"}
我理解这意味着,当它试图保存UserDeviceID对象时,它无法在bundle中找到要放入UserDeviceID模型的ForeignKeyUser字段的数据
有人能解释一下需要做些什么才能使这段代码正常工作吗
谢谢 在当前关系中无法实现它。模型资源是模型的真实反映。例如,您可以创建以下内容:
>>> UserProfile.objects.create(refferal_code='asdfasdf', user=User.objects.create_user(username='asdfasdf'))
或者这个:
>>> UserDeviceIds.objects.create(device_id='adfadf', user=User.objects.create_user(username='asdfasdfas'))
但不是在一个指令中同时使用
RESTAPI很棒,因为它非常适合Django ORM自己的接口
因此,您可以使用子对象创建对象,但不能同时使用其他父对象
您将资源命名为具有功能性目的的创建,这显然表明某些内容不正确。您的资源应仅分配给模型
在我看来,RESTAPI非常适合使用,因为它清晰、易于客户理解、易于规则、快速构建、易于测试。但是feet真的没有很好地与Django签约
如果您必须打破一些RESTful规则,不要试图重新定义现有的功能齐全的资源,这可能会带来很多麻烦。相反,为了实现这一目的,需要对一些自定义的分离端点进行详细描述
我建议创建自定义视图,如端点处理json/xml,无论您支持注册什么。在单独的应用程序中保存它,如果您在将来找到更好的解决方案,您将很容易更换它。我建议这样做是因为:1。在一次通话中创建这三个模型对您来说至关重要,如果互联网中断,它将破坏模型。2.会更快
我怀疑是否有现成的应用程序可以解决这个问题,因为sing up对于每个网站来说都是独一无二的
import json
from django.contrib.auth.models import User
from django.http import (HttpResponse, HttpResponseBadRequest,
HttpResponseNotAllowed)
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def signup(request):
"""
Description:
POST faldksfalskdfjalksdf
Headers:
sdfasdf
Attributes:
sadljfkasdlfksad
Responses:
asdf
"""
if request.method != 'POST':
return HttpResponseNotAllowed(permitted_methods=('POST',))
try:
data = json.loads(request.body)
except (AttributeError, ValueError):
return HttpResponseBadRequest(
json.dumps({'error': 'JSON format invalid',
'success': False}),
content_type='application/json')
if data.get('username', None) and data.get('device_id', None) and data.get('country', None):
# add more validation.
user = User.objects.create_user(username=data['username'])
UserProfile.objects.create(refferal_code='asdfasdf', user=user)
UserDeviceIds.objects.create(device_id='adfadf', user=user)
return HttpResponse(json.dumps({'success': True}),
content_type='application/json')
else:
return HttpResponseBadRequest(
json.dumps({'error': 'username, device_id or country attributes missing.',
'success': False}),
content_type='application/json')
我明白你的意思。如果我为用户模型创建一个资源,然后UserProfile和UserDeviceID将是子对象,那么我应该能够创建这些子模型的对象。。。正当您能否详细说明这种方法的缺点是什么?您可以这样做,并且它可以在一个调用中工作,但是您必须更改模型关系才能更改资源关系。缺点是您使应用程序接口成为数据库体系结构的独裁者。您可能会损失数据库效率,并使其他模型或其他操作过于复杂。
{"error_message": "null value in column \"user_id\" violates not-null constraint
DETAIL: Failing row contains (2, abc, def, ghi, null).
", "traceback": "Traceback (most recent call last):
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/backends/utils.py\", line 65, in execute
return self.cursor.execute(sql, params)
psycopg2.IntegrityError: null value in column \"user_id\" violates not-null constraint
DETAIL: Failing row contains (2, abc, def, ghi, null).
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 201, in wrapper
response = callback(request, *args, **kwargs)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 432, in dispatch_list
return self.dispatch('list', request, **kwargs)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 464, in dispatch
response = method(request, **kwargs)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 1340, in post_list
updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 2104, in obj_create
return self.save(bundle)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 2247, in save
self.save_related(bundle)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 2318, in save_related
related_resource.save(related_bundle)
File \"/vagrant/venv/lib/python3.4/site-packages/tastypie/resources.py\", line 2250, in save
bundle.obj.save()
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/base.py\", line 589, in save
force_update=force_update, update_fields=update_fields)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/base.py\", line 617, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/base.py\", line 698, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/base.py\", line 731, in _do_insert
using=using, raw=raw)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/manager.py\", line 92, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/query.py\", line 921, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/models/sql/compiler.py\", line 920, in execute_sql
cursor.execute(sql, params)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/backends/utils.py\", line 81, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/backends/utils.py\", line 65, in execute
return self.cursor.execute(sql, params)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/utils.py\", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File \"/vagrant/venv/lib/python3.4/site-packages/django/utils/six.py\", line 658, in reraise
raise value.with_traceback(tb)
File \"/vagrant/venv/lib/python3.4/site-packages/django/db/backends/utils.py\", line 65, in execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: null value in column \"user_id\" violates not-null constraint
DETAIL: Failing row contains (2, abc, def, ghi, null).
"}
>>> UserProfile.objects.create(refferal_code='asdfasdf', user=User.objects.create_user(username='asdfasdf'))
>>> UserDeviceIds.objects.create(device_id='adfadf', user=User.objects.create_user(username='asdfasdfas'))
import json
from django.contrib.auth.models import User
from django.http import (HttpResponse, HttpResponseBadRequest,
HttpResponseNotAllowed)
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def signup(request):
"""
Description:
POST faldksfalskdfjalksdf
Headers:
sdfasdf
Attributes:
sadljfkasdlfksad
Responses:
asdf
"""
if request.method != 'POST':
return HttpResponseNotAllowed(permitted_methods=('POST',))
try:
data = json.loads(request.body)
except (AttributeError, ValueError):
return HttpResponseBadRequest(
json.dumps({'error': 'JSON format invalid',
'success': False}),
content_type='application/json')
if data.get('username', None) and data.get('device_id', None) and data.get('country', None):
# add more validation.
user = User.objects.create_user(username=data['username'])
UserProfile.objects.create(refferal_code='asdfasdf', user=user)
UserDeviceIds.objects.create(device_id='adfadf', user=user)
return HttpResponse(json.dumps({'success': True}),
content_type='application/json')
else:
return HttpResponseBadRequest(
json.dumps({'error': 'username, device_id or country attributes missing.',
'success': False}),
content_type='application/json')