Reputation: 1130
I am working on a demo DRF project to develop search and filter feature. However, I am not able to understand the issue with my project. I have some data stored in DB, and the GET is working fine. However, if I am doing some search operations in POSTMAN, I am seeing error, which is beyond my understanding.
I have followed the below DRF official link. Below is the error
raise FieldError('Related Field got invalid lookup: {}'.format(lookup_name))
django.core.exceptions.FieldError: Related Field got invalid lookup: icontains
[12/Jan/2021 11:32:53] "GET /api/shop/?search=Amitesh HTTP/1.1" 500 154116
Below are the project details:
from django.db import models
from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.utils.translation import gettext_lazy as _
class AccountManager(BaseUserManager):
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(email, password, **extra_fields)
def create_user(self, email, password, **extra_fields):
if not email:
raise ValueError(_('Enter the email before proceeding'))
email = self.normalize_email(email)
user = self.model(email=email, password=password, **extra_fields)
user.set_password(password)
user.save()
return user
class Shop(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
shop_name = models.CharField(max_length=150)
contact = models.CharField(max_length=10)
State = models.CharField(max_length=100)
district = models.CharField(max_length=100)
location = models.CharField(max_length=100)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(null=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['shop_name', 'contact', 'is_staff']
def __str__(self):
return str(self.shop_name)
class Medicine(models.Model):
medicine_name = models.ForeignKey(Shop, on_delete=models.CASCADE, max_length=100)
company = models.CharField(max_length=100)
salt_power = models.CharField(max_length=100)
manufacturing_date = models.DateField()
expiry_date = models.DateField()
In_Stock = models.BooleanField()
medicine_Type = models.CharField(max_length=50)
number_available = models.IntegerField()
def __str__(self):
return str(self.medicine_name)
class ShopRESTView(generics.ListCreateAPIView):
permission_classes = (permissions.AllowAny, )
search_fields = ['shop_name', 'State', 'district', 'location', 'aushadhi']
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
queryset = Shop.objects.all()
serializer_class = ShopSerilizer
from rest_framework import serializers
from .models import Shop, Medicine
class MedicineSerializer(serializers.ModelSerializer):
class Meta:
model = Medicine
fields = '__all__'
class ShopSerilizer(serializers.ModelSerializer):
aushadhi = MedicineSerializer(many=True)
class Meta:
model = Shop
fields = ['shop_name', 'contact', 'State', 'district', 'location', 'aushadhi']
Google Drive link, just in case anybody would like to re-produce the issue.
All the migrations and the migrate went on with out any issue.
Please suggest
Upvotes: 0
Views: 324
Reputation: 88429
In your case, the aushadhi
is a "related name" (reverse relation to Medicine
) and can't be searched on that field.
So, change your search_fields
to something like,
class ShopRESTView(generics.ListCreateAPIView):
permission_classes = (permissions.AllowAny,)
search_fields = [
'shop_name',
'State',
'district',
'location',
'aushadhi__company',
'aushadhi__salt_power',
'aushadhi__medicine_Type'
# etc
]
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
queryset = Shop.objects.all()
serializer_class = ShopSerilizer
Upvotes: 1