开发者

Django search multiple filters

开发者 https://www.devze.com 2023-01-30 12:30 出处:网络
Lets say I have a model models.py class user: name = models.CharField(max_length=25) class job: job_name = models.CharField(max_length=25)

Lets say I have a model

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(
            开发者_C百科                              choices = jobs,
                                          widget  = forms.CheckboxSelectMultiple(),
                                          label   = 'Search',
                                         )

I can search for users that have job 'a' with

user_job.objects.filter(job__exact = 'a') ...

I tried to search for users that have both job 'a' and job 'c' like so

search_q = user_job.objects.filter(job__exact = 'a')
search_q = search_q.filter(job__exact = 'c')

but I get all users that have job 'a' or job 'c', and I need all users that have both jobs.

Is there a way I can filter it through Django, or do I need to filter on one job and then iterate through the results and check for the 2nd job?


You'll probably find it easier to search from the User model since what you want is a list of Userss who have both jobs. Django automatically sets up properties on your models that allow you to access related models both from model instances and in DB queries.

Assuming you set up your models like so:

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)

And populate it as follows:

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)

The following query will return you user 3, which is the only user who has both "Job a" and "Job c":

u = User.objects.filter(userjob__job=a).filter(userjob__job=c)

(or, if you prefer to refer to the jobs by name rather than Job instance):

u = User.objects.filter(userjob__job__name='a').filter(userjob__job__name='c')

You can see how Django is allowing you to traverse the related fields from the User model to the UserJob model with the double underscore notation (the Django docs on this are here: http://docs.djangoproject.com/en/1.2/topics/db/queries/#lookups-that-span-relationships.

Once you get the User object back, you can similarly access the UserJob instances using the relationship properties that Django adds to the model:

u = User.objects.filter(userjob__job__name='a').filter(userjob__job__name='c')
jobs = u.userjob_set.all()


pip install django-filter

Then add django-filter in your install apps:

'django_filters'

Then create a new file like 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'
        ]

After that import RentFilter in your views.py then follow the step:

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)

Finally, in your booking_filter.html template look like this:

              <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>

Print the output in your template bottom:

                      <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>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号