I like to make a filter where user can search based on last_name or a regio(region). I made the query but it filters well only if I using the last_name filter, but the regio gives all the users in the db.
I'm used before Sqlite3 and raw queries but now I like to learn ORM with Postgres so I'm not experienced in ORM yet. What am I doing wrong?
models.py
class Profil(models.Model):
def __str__(self):
return str(self.user)
def generate_uuid():
return uuid.uuid4().hex
user = models.OneToOneField(User, on_delete=models.CASCADE)
datetime = models.DateTimeField(auto_now_add=True, auto_now=False)
coach_uuid = models.CharField(default=generate_uuid, editable=True, max_length=40)
regio = models.ForeignKey('Regiok', blank=True, null=True, on_delete=models.CASCADE)
class Regiok(models.Model):
regio = models.CharField(max_length=80)
def __str__(self):
return str(self.regio)
views.py
def coachok(request):
coach = Profil.objects.all()
nev = request.GET.get('nev')
regio = request.GET.get('regio')
if nev != '' and nev is not None or regio != '' and regio is not None:
coach = Profil.objects.filter(Q(user__last_name__icontains=nev) | Q(regio_id__regio=regio)).select_related('user', 'regio')
context = {
'coach':coach,
}
return render(request, 'coachregiszter/coachok.html', context)
html
<div class="container">
<form method="GET">
<div class="bg-light p-2">
<div class="row my-3">
<h4>Szűrők</h4>
<div class="col-md-3">
<h6>Név</h6>
<input class="form-control" type="search" name="nev"></input>
</div>
<div class="col-md-3">
<h6>Vármegye</h6>
<select class="form-select" name="regio">
<option value="" selected>Bármelyik</option>
<option value="Dél-Dunántúl">Dél-Dunántúl</option>
<option value="Közép-Dunántúl">Közép-Dunántúl</option>
</select>
</div>
</div>
<button type="submit" class="btn btn-outline-dark">Keresés</button>
<a href="/coachok"><button type="submit" class="btn btn-outline-info">Szűrők törlése</button></a>
</div>
</form>
Make the queries optional:
from operator import or_
from functools import reduce
# ...
nev = request.GET.get('nev')
regio = request.GET.get('regio')
coach = Profil.objects.all()
queries = []
if nev:
queries.append(Q(user__last_name__icontains=nev))
if regio:
queries.append(Q(regio_id__regio=regio))
if queries:
coach = coach.filter(reduce(or_, queries))
coach = coach.select_related('user', 'regio')