__init__의 Django Forms에서 사용자 지정 제약 조건으로 입력 된 데이터 유효성 검사

Nov 14 2020

내 프로젝트에서 사용자는 응용 프로그램의 설정 페이지에 데이터를 입력하고 있으며 사용자의 설정 기본 설정으로 데이터베이스를 업데이트해야합니다. Alasdair 의이 답변 과을 사용 __init__()하여 사용자의 세부 정보에 액세스하는 방법을 읽었습니다 . 뷰 __init__()에서 save()함수를 호출하기 전에 입력 된 데이터의 유효성을 검사 할 수 있도록 데이터를 반환 할 수 있는지 궁금합니다 . 이것은 내가 시도한 것입니다 (작동하지 않았습니다). 더 나은 접근 방식으로 이에 대해 열려 있으므로 모든 제안에 감사드립니다!

** 편집 : ** 양식 파일에 사용자가 입력 한 데이터의 유효성 검사를 이동하기로 결정하고 있습니다. 왜냐하면 내보기에 작성할 때 5 개의 if 문 (중첩)을 얻었 기 때문입니다. IMO와이 응용 프로그램의 상황을 고려할 때 양식으로 이동하는 것이 더 깨끗한 접근 방식 인 것 같습니다. 또한 clean _ [ 'field'] 사용을 고려했지만이 를 수행 side하려면 __init__()함수 의 변수 가 필요하며 그 값을 추출하는 방법을 모르겠습니다.

Forms.py

class t_max_form(forms.ModelForm):

    side = None

    def __init__(self, *args, **kwargs):
        side = kwargs.pop('side', None)

        super(t_max_form, self).__init__(*args,**kwargs)

        if side == "ms":
            self.fields['hs_max_sessions'].widget.attrs.update({'class':'form-control', 'readonly':True})
            self.fields['ms_max_sessions'].widget.attrs.update({'class':'form-control mb-3'})
        elif side == "hs":
            self.fields['hs_max_sessions'].widget.attrs.update({'class':'form-control'})
            self.fields['ms_max_sessions'].widget.attrs.update({'class':'form-control', 'readonly':True})
        else:
            self.fields['hs_max_sessions'].widget.attrs.update({'class':'form-control'})
            self.fields['ms_max_sessions'].widget.attrs.update({'class':'form-control'})

     
        #Trying to validate the data here
        valid_session_count = settings.objects.first()
        if(side == "ms"):
            input_sessions = self.fields['ms_max_sessions'].widget.attrs['readonly']
            if(input_sessions > valid_session_count.max_sessions):
                self.add_error("ms_max_sessions", "You have entered more than the limit set by the TC. Try again")
         elif(side == "hs"):
             input_sessions = self.cleaned_data['hs_max_sessions']
             if(input_sessions > valid_session_count.max_sessions):
                 self.add_error("hs_max_sessions", "You have entered more than the limit set by the TC. Try again")
         else:
             input_sessions = self.cleaned_data['ms_max_sessions'] + self.cleaned_data['hs_max_sessions']
             if(input_sessions > valid_session_count.max_sessions):
                 self.add_error("hs_max_sessions", "You have entered more than the limit set by the TC. Try again")

        return input_sessions

이것이 제가 제 관점에서 시도한 것입니다.

views.py

def t_time_slots(request):
    name = request.user.username
    t = t_info.objects.get(student__user__username = name)
    timeSlots = tutor_time_slot.objects.filter(tutor = tutor).order_by('time') 
    side = decide_side(request.user)
    
    if request.method == 'POST':
        form = t_time_slot_form(request.POST)

        if form.is_valid():
            if check_unique_time_slot(request.user, form.cleaned_data['day'], form.cleaned_data['time']):
                timeSlots = form.save(commit=False)
                timeSlots.t = t
                timeSlots.save()
                messages.success(request, "Added Successfully")
                return redirect('TTimeSlot')
            else:
                print("Overlap")
                messages.error(request, "The time slot overlaps with a Current one. Please Change the time and try again.")
                return redirect('TTimeSlot')
    else:
        form = t_time_slot_form()
        
    context = {'timeSlots': timeSlots, 'form': form, 'side':side}
    return render(request, 't/t_time_slot.html', context)

답변

1 Alasdair Nov 14 2020 at 17:02

메소드 self.side에서 설정 __init__하면 clean()또는 clean_<field>메소드 에서 액세스 할 수 있습니다 .

__init__메서드 에 유효성 검사 코드를 넣는 것을 피할 것 입니다.

class MyForm(forms.Form):

    my_field = forms.CharField()

    def __init__(self, *args, **kwargs):
        self.side = kwargs.pop('side', None)

        super(t_max_form, self).__init__(*args,**kwargs)
        ...

    def clean_my_field(self):
        my_field = self.cleaned_data['my_field']
        # Use self.side to validate data
        if my_field = self.side:
            raise forms.ValidationError("Invalid")
        return my_field