Nepo Znat
Nepo Znat

Reputation: 3280

Search through queryset with one to one field

I have two models UserDetails and User.

I have a simple search that checks if the string is in one of the fields. My problem is that I don't know how to access the one-to-one field in the queryset below to search through this as well.

class UserDetails(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL, 
    related_name='detail')
    details = models.CharField(max_length=100)

class User(models.Model):
    name = models.CharField(max_length=100)
    desc = models.CharField(max_length=200)
    ...

search = 'John Doe'
User.objects.filter(
    Q(name__icontains=search) |
    Q(desc__icontains=search) |
    Q(__detail_details=search) . # how to do this?
)

Upvotes: 2

Views: 49

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477318

You use double underscores (__) with the related_name on the left. So:

User.objects.filter(
    Q(name__icontains=search) |
    Q(desc__icontains=search) |
    Q(detail__details=search)
)

Or in case you want to add an __icontains lookup:

User.objects.filter(
    Q(name__icontains=search) |
    Q(desc__icontains=search) |
    Q(detail__details__icontains=search)
)

Given search is thus 'John Doe' we will return User objects where the name contains 'John Doe', the desc contains 'John Doe', or the related UserDetail object its details column contains 'John Doe'.

The double underscore can be seen as a way to look "through" relations, and thus access columns of these related objects. You can chain these together in a rel1__rel2__rel3__some_field__some_lookup fashion.

Upvotes: 2

Related Questions