开发者

Django problem with validating forms

开发者 https://www.devze.com 2023-03-03 19:22 出处:网络
I have been trying to figure out how all this validation works, but I am not getting the hang of it. I read the very few examples on djangoproject, but I am missing concepts and how everything is tied

I have been trying to figure out how all this validation works, but I am not getting the hang of it. I read the very few examples on djangoproject, but I am missing concepts and how everything is tied together.

If you could please look at my code and rearrange how things should be, as well as a few explanations, that would be awesome!

So I want to do something very simple: have a login from with email ONLY. When a user types their email, i want to check if it's in the database, and if it is, login. if it is not, i want to raise an error 'user already in database' and suggest that this person goes to /register

So what i currently have is:

view.py:

def emailLogin(request, backend, extra_context=None, initial={}):

form = EmailLoginForm(ini开发者_运维技巧tial=initial)
if request.method == 'POST':
    form = EmailLoginForm(initial=initial, data=request.POST)
    if form.is_valid():
        user = form.do_save()

        _no_pass_login(request, user) # my custom login
        return redirect('/')

    else:
        print ('not valid')

return render_jinja(request, 'registration/email_login_form.html',
        type="register",
        form = form
        )

forms.py:

class EmailLoginForm(forms.Form):
    email = forms.EmailField()
    def do_save(self):
    try:
            u = User.objects.get(email=self.cleaned_data['email'])
        except :
            raise forms.ValidationError("Already in DB")

        return u

So the whole point is that I am missing concepts - where should a validation error be raised, the view or the form? where is it raised to? who catches it? what needs to be imported in each file etc.

This shouldn't be too difficult but i am totally lost now, and i have no examples I can analyze and mod my code to work, so i am here.


Yes, you do seem to be missing some concepts.

This type of form shouldn't have a save at all. And the whole point of the is_valid() check is to catch the validation errors - so they should be raised by that call. The way to do that is to define clean methods on the form. In this case, since you're only checking the email field, you define a clean_email method. The code should be identical to what you've currently got in do_save.

Now, is_valid() will return False. But there are a couple of tweaks needed in your view to actually show the errors. First, bring that else block back one indent level, so it matches if request.method == 'POST'. Now, instead of that print statement, move the first line - form = EmailLoginForm(initial=initial) in there. Now, when is_valid() is False, the view will fall straight through to the render_to_response with an already-instantiated form containing the validation errors. Magic!


I think this is what Daniel was talking about, but it can be confusing if you don't know exactly what's going on. Basically, all the form does is validate your data. All the saving is done in the view.

view.py

def emailLogin(request, backend, extra_context=None, initial={}):

    form = EmailLoginForm
    if request.method == 'POST':
        form = form(initial=initial, data=request.POST)
        if form.is_valid():
            _no_pass_login(request, user) # my custom login
            return redirect('/')
        else:
            print 'Form not valid'

    else:
        form = form(initial=initial)

return render_jinja(request, 'registration/email_login_form.html',
    type="register",
    form = form
    )

forms.py

class EmailLoginForm(forms.Form):

    email = forms.EmailField()

    def clean_email(self, *args, **kwargs):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).count() > 0:
            raise ValidationError('User with email "%s" already exists' % email)
        return email
0

精彩评论

暂无评论...
验证码 换一张
取 消