0

I need to filter Users (from auth.user) based on their full names. I know I can address a user's full name by user.get_full_name(), but is it possible to filter by this attribute?

I need to do something like, user = User.objects.filter( ... ), but I need to feed it an attribute. Is there some attribute that I can use for this?

Daniel Rosenthal
  • 1,386
  • 4
  • 15
  • 32

2 Answers2

1

Not as a property, unfortunately.

The available properties in the Django User model are

  • username
  • password
  • email
  • first name
  • last name

But doing the filter anyways would look like this

User.object.filter(first_name="Jimminy", last_name="Cricket")

What you could do is create a custom form of profile.

class UserProfile(models.Model):
   full_name = models.CharField()
   user = models.ForeignKey(User)

   def save(self, *args, **kwargs):
      self.full_name = "Jimminy Cricket" #but not hardcoded ofc.
      super(UserProfile, self).save(*args, **kwargs)

and filter on it like so

profile = UserProfile.objects.get(full_name="Jimminy Cricket")
print profile.user

Update 15/4-2018

You could also do achieve the same by using the Q object

from django.db.models import Q
from django.contrib.auth import get_user_model

UserModel = get_user_model()
UserModel.objects.filter(Q(first_name='Jiminy'), Q(last_name='Cricket'))

Which would output the following SQL

'SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE ("auth_user"."first_name" = Jiminy AND "auth_user"."last_name" = Cricket)'

And thusly getting rid of the intermediate model/form.

Henrik Andersson
  • 45,354
  • 16
  • 98
  • 92
  • Yes. I guess this is the best I can do. I'll split the input (from the user): `name=name.split(' ')`, and then `user = User.objects.filter(first_name=name[0], last_name=name[1])` – Daniel Rosenthal Jul 29 '13 at 19:11
  • This seems like the best solution, but also an example of a pretty extreme limitation of Django's query language! – Niels Abildgaard Apr 14 '18 at 19:20
  • @NielsAbildgaard I wouldn't necessary call it limited - i mean `get_full_name` is still a python property and not related to SQL at all. If you want to drop down to raw SQL that's possible otherwise using the `Q` object would also help here. `User.objects.filter(Q(first_name='Jiminy'), Q(last_name='Cricket'))` I believe. – Henrik Andersson Apr 15 '18 at 01:21
1

To filter based on a User's full name, you could first annotate the queryset with each user's full name and then filter on that annotation.

from django.db.models import Value
from django.db.models.functions import Concat


User.objects.annotate(
    full_name=Concat('first_name', Value(' '), 'last_name')
).filter(full_name__icontains='J Biz')
jbiz
  • 394
  • 1
  • 5