我想知道使用TastyPie验证的正确方法是什么。 我有以下资源和模型:
from tastypie.resources import ModelResource
class Station(models.Model):
name = models.CharField(max_length=20)
city = models.ForeignKey(City)
class StationResource(ModelResource):
city = fields.ForeignKey(CityResource, 'city')
class Meta:
queryset = caModels.Station.objects.all()
resource_name = 'Station'
authorization = Authorization()
validation=FormValidation(form_class=StationForm)
max_limit = None
我还想使用ModelForm来验证数据:
class StationForm(forms.ModelForm):
class Meta:
model = caModels.Station
def clean_city(self):
return self.cleaned_data['city']
以下查询正常工作:
curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"city": "/resources/City/89/", "name": "station_1", <and other fields here>}' "http://localhost:8000/resources/Station/?format=json"
HTTP/1.0 201 CREATED
Date: Thu, 06 Feb 2014 13:10:14 GMT
Server: WSGIServer/0.1 Python/2.7.4
Vary: Accept, Cookie
Content-Type: text/html; charset=utf-8
Location: http://localhost:8000/resources/Station/3/
但是当我从请求中移除城市(但需要此字段)而不是消息“此字段是必需的”时,我得到以下追溯:
Traceback (most recent call last):
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 77, in wrapped_view
return view_func(*args, **kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 217, in wrapper
response = callback(request, *args, **kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 459, in dispatch_list
return self.dispatch('list', request, **kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 491, in dispatch
response = method(request, **kwargs)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 1357, in post_list
updated_bundle = self.obj_create(bundle, **self.remove_api_resource_names(kwargs))
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 2149, in obj_create
bundle = self.full_hydrate(bundle)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/resources.py", line 909, in full_hydrate
value = field_object.hydrate(bundle)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/fields.py", line 732, in hydrate
value = super(ToOneField, self).hydrate(bundle)
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/tastypie/fields.py", line 165, in hydrate
elif self.attribute and getattr(bundle.obj, self.attribute, None):
File "/home/ak/venv/main_env/local/lib/python2.7/site-packages/django/db/models/fields/related.py", line 389, in __get__
raise self.field.rel.to.DoesNotExist
DoesNotExist
甚至在我可以验证表单中的数据之前就会发生此错误(验证是保存过程的第一个过程)。
.../tastypie/resources.py:
def obj_create(self, bundle, **kwargs):
"""
A ORM-specific implementation of ``obj_create``.
"""
bundle.obj = self._meta.object_class()
for key, value in kwargs.items():
setattr(bundle.obj, key, value)
self.authorized_create_detail(self.get_object_list(bundle.request), bundle)
bundle = self.full_hydrate(bundle)
return self.save(bundle)
def save(self, bundle, skip_errors=False):
self.is_valid(bundle)
...
有人可以指出我错在哪里,或者可能是我错过了什么,从TastyPie的角度来看,这种验证方式是完全错误的吗?
答案 0 :(得分:0)
我认为你的问题非常有趣 我决定在主题中挖掘一下..
这是我发现的。
文档:
blank
我们看到这个描述与我们从Django已经知道的很相似。
代码库: hydrate 如果你没有明确说明Tastypie会“期望”这个领域在那里。
简短的结论:我认为资源类似于模型之外的东西,Meta可能会对需求有很大的不同,这可以为您提供更多的灵活性。
潜在的解决方案:
对Tastypie说,如果它的空白则传递给它。无论如何模型验证都不会通过它。
class StationResource(ModelResource):
city = fields.ForeignKey(CityResource, 'city', blank=True)
或者添加默认水合物。
class StationResource(ModelResource):
city = fields.ForeignKey(CityResource, 'city')
def hydrate(self, bundle):
if not hasattr(bundle, 'city'):
bundle.data['city'] = None
return bundle
结论:这实际上很容易引起误解,但另一方面Tastypie仍处于开发阶段,也许文档会更好地覆盖它,或者这会改变,或者有计划改变它。
如果您对此感兴趣,可以在github上讨论许多问题:类似于您的问题:issue