简体   繁体   中英

simple auth system in django failing

I'm writing a simple auth system to login (and logout) users. The username is an email address, which looks up an email field.

I'm using:

user = User.objects.get(email__exact=email)
# if user obj exists
if user:
    # if authenticate
    if authenticate(user, email, password):
        # create session
        request.session['user'] = user
        # redir
        return HttpResponseRedirect('/home/')
    else:
        return HttpResponseRedirect('/home/login/')
# no user obj found? (no email found actually)
else:
    # redir
    return HttpResponseRedirect('/home/')

to find if a user exists, however if a user is not found Django throws an error:

User matching query does not exist.

All I want to do is see if that query matches a result. How do I count rows?

使用filter()代替get()

I think this is probably more what you want:

try:
    user = User.objects.get(email__exact=email)
    if authenticate(user, email, password):
        request.session['user'] = user
        return HttpResponseRedirect('/home/')
    else:
        return HttpResponseRedirect('/home/login/')
except User.DoesNotExist: # A user with the e-mail provided was not found
    return HttpResponseRedirect('/home/')

Personally I think that's cleaner than Ignacio's method, but it's a matter of taste really.

Finally, the last part of your question ("How do I count rows?"):

get only ever returns an object, and raises an exception if no objects match the criteria you passed in, or if multiple objects match the criteria. To get the number of objects in a QuerySet , you can just call len on it:

q = User.objects.filter(email = 'foo@bar.com')
print len(q)

Or, call count() :

print User.objects.filter(email = 'foo@bar.com').count()

The former method ( len ) will be quicker if you've already evaluated the QuerySet (since it's just counting the number of items in a list, effectively); the latter ( count() ) will be faster if you've not evaluated the QuerySet , since Django will perform a SELECT COUNT(*) behind the scenes, and you avoid loading all the data into memory.

As an aside - why are you directing them to /home/ if the e-mail address isn't matched, and to /home/login/ if their credentials fail? I would have thought it makes more sense to redirect them to the same place for those two cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM