2014-02-06 40 views
1

我不知道什么是使用TastyPie验证的正确方法。 我有以下的资源和型号: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

我认为你的问题很有意思。
我决定挖掘一点主题..

这是我找到的。

  1. 文档: blank
    正如我们看到的这种描述是非常类似于我们已经从Django的认识。

  2. 代码库: hydrate 如果不明确地说Tastypie会不会“期望”这个领域在那里。

短的结论:我觉得像资源超出了模型的东西和元可能是非常不同的问候需求,可以给你,例如更大的灵活性。

潜在的解决方案:

  1. 说到Tastypie如果空白传递。无论如何模型验证不会通过它。

    class StationResource(ModelResource): 
        city = fields.ForeignKey(CityResource, 'city', blank=True) 
    
  2. 或者添加默认水合物。

    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

+0

谢谢!在我看来,使用blank = True的情况在任何情况下都会有点误导(因为实际上这个字段实际上是必填字段)。我也想过“水合物”的方法(可能会更好地实施内部验证): def hydrate_city(self,data): bundle.errors ['city'] ='此字段是必需的' raise ImmediateHttpResponse(...) – Andrey