I have two models named user, skill, and profile. I am trying to implement a search filter on the user's skills. which means when someone searches for something that is contained in the skills of a user, that user would appear in the search result.
Note: when the user signs up, a signal is used to auto-create a profile for that user. The user simply updates their profile to add skills and other things.
user model
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
name = models.CharField(max_length=250)
picture = models.TextField(null=True, blank=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
slug = models.SlugField(max_length=255, unique=True, blank=True)
profile model
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profiles')
date_of_birth = models.DateField(blank=True, verbose_name="DOB", null=True)
bio = models.TextField(max_length=500, blank=True, null=True)
skills = models.ManyToManyField(Skill, related_name='skills')
sex = models.CharField(max_length=6, choices=SEX, blank=True, null=True)
type_of_body = models.CharField(max_length=8, choices=BODYTYPE, blank=True, null=True)
feet = models.PositiveIntegerField(blank=True, null=True)
inches = models.PositiveIntegerField(blank=True, null=True)
lives_in = models.CharField(max_length=50, blank=True, null=True)
updated_on = models.DateTimeField(auto_now=True)
skill model
class Skill(models.Model):
name = models.CharField(max_length=60)
subcategory = models.CharField(max_length=60, blank=True, null=True)
description = models.TextField(null=True, blank=True)
created_on = models.DateTimeField(auto_now=True)
updated_on = models.DateTimeField(auto_now_add=True)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.DO_NOTHING)
the user view, where the search is done from
class ListUsersView(generics.ListAPIView):
'''
Gets all the users in the database
'''
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [AllowAny]
filter_backends = [filtr.SearchFilter]
search_fields = ['email', 'name']
currently, the solution above works, but when I add to the search_fields
other fields like profiles__skills
in order to include results where there is a skill like that created by ay user, the code doesn't work.
Please, how can I get the skills in the profile of a user to show in the search?
The SearchFilter class supports simple single query parameter based searching. The search_fields attribute should be a list of names of text type fields on the model.
profiles__skills is not a field. You should use a text field eg. profiles__skills__name
class ListUsersView(generics.ListAPIView):
'''
Gets all the users in the database
'''
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [AllowAny]
filter_backends = [filtr.SearchFilter]
search_fields = ['email', 'name', 'profiles__skills__name']