I have an html page in which one can search for a car based on several criteria. How do I tell django orm to return all if a field is empty? I checked this question and implemented the same idea of the first answer but it doesn't work for the foreign fields especially the model field, which if left empty, I get this error.
models.py:
class City(models.Model):
name = models.CharField(max_length=10, null=True)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, null=True, blank=True)
class PowerSource(models.Model):
source = models.CharField(max_length=8)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Manufacturer(models.Model):
manufacturer = models.CharField(max_length=45)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class CarModel(models.Model):
model = models.CharField(max_length=45)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
manufacturer = models.ForeignKey(Manufacturer, related_name='car_models', on_delete=models.CASCADE)
class Car(models.Model):
color = models.CharField(max_length=10, null=True)
year = models.IntegerField(null=True, validators=[MinValueValidator(datetime.today().year-120), MaxValueValidator(datetime.today().year+1)])
num_passengers = models.IntegerField(validators=[MinValueValidator(1)], null=True)
transmission = models.CharField(max_length=9, null=True)
status = models.CharField(max_length=4, null=True)
price = models.IntegerField(validators=[MinValueValidator(1)], null=True)
bhp = models.IntegerField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
city = models.ForeignKey(City, related_name='cars', on_delete=models.CASCADE)
power_source = models.ForeignKey(PowerSource, related_name='cars', on_delete=models.CASCADE)
model = models.ForeignKey(CarModel, related_name='cars', on_delete=models.CASCADE)
def get_all_cities():
return City.objects.all()
def get_city(request):
if request.POST['city'] != 'None':
name = request.POST['city']
return City.objects.get(name=name)
else:
get_all_cities()
def get_all_manufacturers():
return Manufacturer.objects.all()
def get_manufacturer(request):
print('getting manufacturer')
if request.POST['manufacturer'] != 'None':
return Manufacturer.objects.get(manufacturer=request.POST['manufacturer'])
else:
get_all_manufacturers()
def get_car_model(request):
if request.POST['manufacturer'] != 'None' and request.POST['model'] != 'None':
return CarModel.objects.get(model=request.POST['model'], manufacturer=get_manufacturer(request))
elif request.POST['model'] == 'None': # model cannot be selected without manufacturer
return CarModel.objects.filter(manufacturer=get_manufacturer(request))
def get_all_sources():
return PowerSource.objects.all()
def get_power_source(requset):
if requset.POST['power_source'] != 'None':
source = requset.POST['power_source']
return PowerSource.objects.get(source=source)
else:
get_all_sources()
def get_searched_cars(request):
query = {}
if request.POST['color']:
query['color'] = request.POST['color']
if request.POST['year']:
query['year'] = request.POST['year']
if request.POST['num_passengers']:
query['num_passengers'] = request.POST['num_passengers']
if request.POST['transmission']:
query['transmission'] = request.POST['transmission']
if request.POST['status']:
query['status'] = request.POST['status']
if request.POST['price']:
query['price'] = request.POST['price']
if request.POST['bhp']:
query['bhp'] = request.POST['bhp']
if request.POST['city'] and request.POST['power_source'] and request.POST['model']:
query['city'] = get_city(request)
query['power_source'] = get_power_source(request)
query['model'] = get_car_model(request)
return Car.objects.filter(**query)
elif request.POST['city'] and request.POST['power_source'] and request.POST['manufacturer']:
query['city'] = get_city(request)
query['power_source'] = get_power_source(request)
return Car.objects.filter(**query, model__in=get_manufacturer(request).car_models.all())
The if statements are not yet complete yet but I wanted to try if it works. I know it's cumbersome to add all if statements but I tried a for loop and it didn't work.
views.py
def search_car(request):
cars_qs = models.get_searched_cars(request)
cars = []
for car in cars_qs:
item = [car.id, car.model.model, car.model.manufacturer.manufacturer]
cars.append(item)
request.session['cars'] = cars
return redirect('/dashboard')
For example, if I choose a manufacturer and leave other fields empy I should get all cars from that manufacturer regardless of color, year, etc. However, I get the aforementioned error. If I choose a manufacturer and a model I don't get the error but the search result is empty. Any ideas?