96

I need to check if Model.objects.filter(...) turned up anything, but do not need to insert anything. My code so far is:

user_pass = log_in(request.POST)  # form class
if user_pass.is_valid():
    cleaned_info = user_pass.cleaned_data
    user_object = User.objects.filter(email = cleaned_info['username'])
tshepang
  • 12,111
  • 21
  • 91
  • 136
sinθ
  • 11,093
  • 25
  • 85
  • 121
  • 1
    i don't understand what you are trying to do. Are you trying to check if a user already exists in order to raise an error? Why do you need to check that? And why are you doing this in a "form view"? Try to answer this question to see if we can help you better... Add a context to your problem, not just the question you have in mind. Sometimes the problem you think you have is not the real problem so your question you asked is not the correct... – marianobianchi Jul 30 '12 at 03:07
  • 2
    Possible duplicate of [what is the right way to validate if an object exists in a django view without returning 404?](http://stackoverflow.com/questions/639836/what-is-the-right-way-to-validate-if-an-object-exists-in-a-django-view-without-r) – Wtower Apr 17 '17 at 19:39

6 Answers6

196

I think the easiest from a logical and efficiency point of view is using the queryset's exists() function, documented here:

https://docs.djangoproject.com/en/stable/ref/models/querysets/#django.db.models.query.QuerySet.exists

So in your example above I would simply write:

if User.objects.filter(email = cleaned_info['username']).exists():
    # at least one object satisfying query exists
else:
    # no object satisfying query exists
phoenix
  • 7,988
  • 6
  • 39
  • 45
mpaf
  • 6,597
  • 6
  • 38
  • 42
78

Since filter returns a QuerySet, you can use count to check how many results were returned. This is assuming you don't actually need the results.

num_results = User.objects.filter(email = cleaned_info['username']).count()

After looking at the documentation though, it's better to just call len on your filter if you are planning on using the results later, as you'll only be making one sql query:

A count() call performs a SELECT COUNT(*) behind the scenes, so you should always use count() rather than loading all of the record into Python objects and calling len() on the result (unless you need to load the objects into memory anyway, in which case len() will be faster).

num_results = len(user_object)
joneshf
  • 2,296
  • 1
  • 20
  • 27
  • 105
    While `.count()` does work, you can also use `.exists()`. https://docs.djangoproject.com/en/dev/ref/models/querysets/#exists – Derek Kwok Jul 30 '12 at 02:17
  • 4
    I'd add to the above comment that while .count() does work, it will be slower than .exists() if the count > 1 and the bigger the count the slower it will become – Bob Oct 02 '14 at 04:26
10

If the user exists you can get the user in user_object else user_object will be None.

try:
    user_object = User.objects.get(email = cleaned_info['username'])
except User.DoesNotExist:
    user_object = None
if user_object:
    # user exist
    pass
else:
    # user does not exist
    pass
Daniel Holmes
  • 1,952
  • 2
  • 17
  • 28
paras chauhan
  • 777
  • 4
  • 13
7

the boolean value of an empty QuerySet is also False, so you could also just do...

...
if not user_object:
   do insert or whatever etc.
David Lam
  • 4,689
  • 3
  • 23
  • 34
  • 4
    this is not very efficient as it will evaluate the query, and when objects do exists it will load them into memory – mpaf Feb 13 '14 at 09:50
6

You can also use get_object_or_404(), it will raise a Http404 if the object wasn't found:

user_pass = log_in(request.POST) #form class
if user_pass.is_valid():
    cleaned_info = user_pass.cleaned_data
    user_object = get_object_or_404(User, email=cleaned_info['username'])
    # User object found, you are good to go!
    ...
César
  • 9,939
  • 6
  • 53
  • 74
4

You can use:

try:
   # get your models
except ObjectDoesNotExist:
   # do something
acarayol
  • 137
  • 2
  • 8