2014-02-06 3 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 지점에서 완전히 잘못입니다

.../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) 
    ... 

는 누군가가 날 지점 수 있습니까?

답변

0

나는 귀하의 질문이 매우 흥미 롭다고 생각합니다.
주제에 조금 들어가기로했습니다.

다음은 내가 찾은 것입니다.

  1. 워드 프로세서 : blank
    우리는이 설명을 우리가 이미 장고에서 알고있는 것과 매우 유사하다시피 .

  2. 코드베이스 : 당신이 명시 적으로 언급하지 않는 경우 hydrate 가 Tastypie이 필드가 될 "기대"않는 것입니다.

짧은 결론 : 모델을 뛰어 넘는 자원과 메타가 많이 달라질 수 있습니다. 예를 들어 더 유연하게 사용할 수 있습니다.

잠재적 인 솔루션 :

  1. 는 빈 경우를 통과 Tastypie에 말. 어쨌든 모델 검증은 통과하지 못할 것입니다.

  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

감사합니다 : 귀하의 질문에 유사한 이와 같은이!실제로이 필드는 실제로 필수 필드이기 때문에 내 의견으로는 공백 = True는 어떤 경우에는 오도 된 것입니다. 나는 또한 "hydrate"방법에 대해 생각해 봤다. (내부의 유효성 검사와 같은 것을 구현하는 것이 더 좋을지도 모른다.) def hydrate_city (self, data) : bundle.errors [ 'city'] = '이 필드는 필수 필드이다. raise ImmediateHttpResponse (...) – Andrey