2012-01-18 3 views
1

내 완벽주의의 방식으로, 나는 잘 - 잘 - 문서화 된 클래스 기반 견해에 대해 더 많은 질문을하기 위해 왔습니다.get 요청에 양식 유효성 검사, 어떻게합니까?

나는 코드에 숨어있는 클래스 기반 뷰에 대해 5 시간을 배우며 질문을 받는다.

아마 내가하려는 것은 어리석은 짓이며, 그렇다면 그렇게 말하십시오.

나는 간단한 예를 둘 것이다 : (? 그것은 바로입니다)

class SearchFormView(FormView): 
    template_name = 'search/search.html' 
    form_class = SearchForm 

    def get(self, request, *args, **kwargs): 
     form = SearchForm(self.request.GET or None) 
     if form.is_valid(): 
      self.mystuff = Stuff.objects.filter(title__icontains=form.cleaned_data['query'])[:10] 

     return super(SearchFormView, self).get(request, *args, **kwargs) 

이 완벽한 유효 클래스입니다.

양식이 있고 쿼리 매개 변수로 GET 요청을합니다.

매력처럼 작동합니다.

그러나 상상해보십시오. 일부 유형의 공격을 막기 위해 쿼리 입력의 유효성을 검사하고 쿼리가 악의적 인 것으로 확인되어 유효성 검사 오류가 발생합니다.

이전 함수에서는 폼 인스턴스 (비어 있음)가 있고 필요한 경우 유효성 검사 오류가 있습니다. 비어있는 경우 (첫 번째 요청) 또는 오류로 가득 찬 경우 (악의적 인 쿼리의 경우) 항상 인스턴스를 반환합니다.

문제는 클래스 기반보기에 있습니다. 내 get 메서드에서는 SearchForm의 추가 인스턴스로 작업하므로 유효성 검사 항목을 넣으면 아버지에 가져 오면 인스턴스가 "form_class"에 비어있게됩니다.

그래서 항상 같은 양식을 사용하는 방법이 있어야한다고 생각합니다. 요청 방법을 호출하고 form_class (새 양식을 만들지 않음)를 선택하고 데이터를 전달하고 유효성을 검사합니다. 아버지는 유효성 확인 자료로 해당 양식을 제출할 것입니다.

정확하게 설명했는지 확실하지 않습니다. 그래서 요컨대 양식의 복사본을 만드는 중이 야하지만 아버지는이 비어있는 다른 복사본을 가지고 있으므로 템플릿을 표시 할 때 보낸 양식이 비어있어 오류가 발생하지 않습니다. .

아이디어가 있으십니까? 감사.

답변

3

문제는 super(SearchFormView, self).get(request, *args, **kwargs)이 자체 양식 및 자체 컨텍스트를 렌더링한다는 것입니다. 그것은 단지 3 라인 뷰 기능이기 때문에, 당신은 당신이 그것의 행동을 바꾸는 데 필요한 것을 무시해야합니다.

def get(self, request, *args, **kwargs): 
     form = SearchForm(self.request.GET or None) 
     if form.is_valid(): 
      self.mystuff = Stuff.objects.filter(title__icontains=form.cleaned_data['query'])[:10] 

     return self.render_to_response(self.get_context_data(form=form)) 

업데이트 : 대체 아이디어 당신은 슈퍼 호출을 계속 사용하려는 경우

def get(self, request, *args, **kwargs): 
    self.form = SearchForm(self.request.GET or None) 
    if self.form.is_valid(): 
     self.mystuff = Stuff.objects.filter(title__icontains=form.cleaned_data['query'])[:10] 

    return super(SearchFormView, self).get(request, *args, **kwargs) 


def get_form(self, form_class): 
    """ 
    Returns an instance of the form to be used in this view. 
    """ 
    return getattr(self, 'form', None) or form_class(**self.get_form_kwargs()) 
+0

내 아이디어 중 하나 였지만 우리가 FormView를 중개했기 때문에 좋지 않다고 생각합니다. form을 검증하기 위해 form_class 속성을 가지고 있습니다.하지만 아버지를 부르지 않으면 그 중 아무 것도 작동하지 않아, 내가 무슨 뜻인지 이해 하겠니? –

+1

FormView가 어떻게 깨지는지 모르겠다. GET에서 유효성 검사를하고 POST는 평소처럼 진행될 것이다. 부모 함수'get'을 실제로 사용하고자한다면, self.form이 존재하면'form_class'를 override하여 self.form을 반환하고, get 함수에서 self.form을 정의 할 수 있습니다. –

+0

글쎄, 나는 첫 번째 대안을 선호한다. 두 번째 것은 더 해키 한 것이다. 감사. –

0
문제는 장고 클래스를 기반으로보기는 양식 kwargs로하는 경우를 채울 수 있다는 사실로 나타납니다

HTTP 메서드는 POST 또는 PUT입니다.

class FormMixin(object): 

    def get_form_kwargs(self): 
     """ 
     Returns the keyword arguments for instanciating the form. 
     """ 
     kwargs = {'initial': self.get_initial()} 
     if self.request.method in ('POST', 'PUT'): 
      kwargs.update({ 
       'data': self.request.POST, 
       'files': self.request.FILES, 
      }) 
     return kwargs 

나는 이따금 씩 특이한 것을 발견했습니다. GET 요청 양식 (예 : "검색"양식), 몇 가지 기본 유효성 검사를 수행해야했습니다.HTTP 메소드가 GET 인 경우에도 kwargs [ 'data'] 항목을 채우기 위해 이러한 뷰에서 get_form_kwargs() 메소드를 대체합니다.