Django搜索多个过滤器
假设我有一个模型
models.py
class user:
name = models.CharField(max_length=25)
class job:
job_name = models.CharField(max_length=25)
class user_job:
user = models.ForeignKey('user')
job = models.ForeignKey('job')
forms.py
jobs = (
('0', 'a'),
('1', 'b'),
('2', 'c'),
)
class searchForm:
box = forms.ModelMultipleChoiceField(
choices = jobs,
widget = forms.CheckboxSelectMultiple(),
label = 'Search',
)
我可以用下面的方法搜索到工作是'a'的用户
user_job.objects.filter(job__exact = 'a') ...
我尝试用下面的方法搜索同时拥有工作'a'和工作'c'的用户
search_q = user_job.objects.filter(job__exact = 'a')
search_q = search_q.filter(job__exact = 'c')
但是我得到的是所有工作是'a' 或者 工作是'c'的用户,而我需要的是同时拥有这两份工作的用户。
有没有办法通过Django来过滤,还是说我需要先过滤出一种工作,然后再遍历结果检查第二种工作呢?
2 个回答
0
pip install django-filter
接下来,在你的安装应用里添加 django-filter:
'django_filters'
然后创建一个新文件,比如叫 filter.py
:
import django_filters
from rent.models import Rent
from django.views import View
class RentFilter(django_filters.FilterSet):
class Meta:
model = Rent
fields = [
'name', 'bed_room', 'bath_room', 'rent_location', 'types'
]
之后在你的 views.py
文件中导入 RentFilter
,然后按照下面的步骤进行:
class BookingFilerListView(View):
def get(self, request):
booking_list = Booking.objects.all()
booking_filer = BookingFilter(request.GET, queryset=booking_list)
template = 'booking/booking_filter.html'
ctx = {'result': booking_filer}
return render(request, template, ctx)
最后,在你的 booking_filter.html
模板中应该是这样的:
<form method="get">
<div class="card-body">
<div class="form-group">
<label for="phone_number">Phone Number</label>
<input type="text" class="form-control" placeholder="Phone Number" name="phone_number">
</div>
<div class="form-group">
<label for="transaction_id">Transaction ID</label>
<input type="text" class="form-control" placeholder="Transaction ID" name="transaction_id">
</div>
<div class="form-group">
<label for="booking_date">Booking Date</label>
<input type="date" class="form-control" placeholder="Booking Date" name="booking_date">
</div>
<div class="form-group">
<label for="status">Booking Date</label>
<select class="form-control" name="status" id="status">
<option value="0">PENDING</option>
<option value="1">CANCEL</option>
<option value="2">PROGRESS</option>
<option value="3">DONE</option>
</select>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success">Filter Booking</button>
<button type="reset" class="btn btn-danger">Reset</button>
</div>
</form>
在你的模板底部打印输出:
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Phone Number</th>
<th>Transaction ID</th>
<th>Booking Date</th>
</tr>
</thead>
<tbody>
{% if result %}
{% for obj in result.qs %}
<tr>
<td>{{ obj.phone_number }}</td>
<td>{{ obj.transaction_id }}</td>
<td>{{ obj.booking_date }}</td>
</tr>
{% endfor %}
{% else %}
{% endif %}
</tbody>
</table>
10
你可能会发现,从 User
模型开始搜索会更简单,因为你想要的是一个同时拥有两个工作的 Users
的列表。Django 会自动在你的模型上设置一些属性,这样你就可以通过模型实例和数据库查询来访问相关的模型。
假设你是这样设置你的模型的:
from django.db import models
class User(models.Model):
name = models.CharField(max_length=25)
def __repr__(self):
return '<User: %s>' % self.name
class Job(models.Model):
name = models.CharField(max_length=25)
def __repr__(self):
return '<Job: %s>' % self.name
class UserJob(models.Model):
user = models.ForeignKey(User)
job = models.ForeignKey(Job)
def __repr__(self):
return '<UserJob: %s %s>' % (self.user.name, self.job.name)
并且像这样填充数据:
u1 = User.objects.create(name='u1')
u2 = User.objects.create(name='u2')
u3 = User.objects.create(name='u3')
a = Job.objects.create(name='a')
b = Job.objects.create(name='b')
c = Job.objects.create(name='c')
UserJob.objects.create(user=u1, job=a)
UserJob.objects.create(user=u2, job=a)
UserJob.objects.create(user=u2, job=b)
UserJob.objects.create(user=u3, job=a)
UserJob.objects.create(user=u3, job=c)
接下来这个查询会返回用户 3,因为只有这个用户同时拥有“工作 a”和“工作 c”:
u = User.objects.filter(userjob__job=a).filter(userjob__job=c)
(或者,如果你更喜欢用工作名称而不是工作实例来引用工作):
u = User.objects.filter(userjob__job__name='a').filter(userjob__job__name='c')
你可以看到,Django 允许你通过双下划线的方式,从 User
模型遍历到 UserJob
模型(关于这方面的详细信息可以查看 Django 文档:http://docs.djangoproject.com/en/1.2/topics/db/queries/#lookups-that-span-relationships)。
一旦你得到了 User
对象,你也可以使用 Django 为模型添加的关系属性,类似地访问 UserJob 实例:
u = User.objects.filter(userjob__job__name='a').filter(userjob__job__name='c')
jobs = u.userjob_set.all()