Как фильтровать на основе результатов предыдущих запросов Django - PullRequest
0 голосов
/ 18 февраля 2019

На данный момент у меня есть 2 отдельных набора запросов, которые отображаются независимо друг от друга на одной странице.

Q1 = users

Q2 = f

Q1 возвращает всех пользователей в радиусе, опубликованном пользователем (request.POST).

Q2 возвращает django_filters.FilterSet в зависимости от выбранного фильтра (цвет волос, возраст и т. Д.) (request.GET)

Q2 должен фильтровать только результаты Q1,Я хотел бы сохранить все это на одной странице, а не перенаправлять на разные URL.

Если бы кто-то мог объяснить самый простой способ сделать это, я был бы очень признателен.

просмотров.py

class ConnectView(View):
    template_name = 'connect/home.html'
    def get(self, request, *args, **kwargs):
        filter = ProfileFilter(request.GET.getlist('filter'))
        context = {
            'users': User.objects.exclude(username=request.user),
            'filter': filter
        }
        return render(request, self.template_name, context)

    def post(self, request, *args, **kwargs):
        if 'latitude' in request.POST and 'longitude' in request.POST:
            try:
                location = Location(latitude=request.POST['latitude'], longitude=request.POST['longitude'], user = request.user)
                location.save()
            except:
                return JsonResponse({'message': 'location already stored!'})

        if 'radius' in request.POST:
            radius_km = request.POST.get('radius', 0)
            queryset = User.objects.annotate(
                radius_sqr=pow(models.F('loc__latitude') -
                request.user.loc.latitude, 2) + pow(models.F('loc__longitude') -
                request.user.loc.longitude, 2)
                ).filter(
                radius_sqr__lte=pow(int(radius_km) / 9, 2)
                ).exclude(username=request.user)
            filter = ProfileFilter(request.POST, queryset=queryset)
            messages.success(request, f'See the results of your search below.')
            return render(request, self.template_name)

        else:
            return render(request, self.template_name)

filters.py

class ProfileFilter(django_filters.FilterSet):
    class Meta:
        model = Profile
        fields = {
            'age': ['exact'],
            'interest': ['exact'],
        }

connecthome.html

  <form method="POST">
    {% csrf_token %}
    <h4>Enter a Distance.</h4>
    <input type="number" name="radius">
    {{ filter.form|crispy }}
    <button type="submit">Search.</button>
  </form>

    {% if filter %}
        {% for profile in filter %}
            <h5>{{ profile.user.first_name }}</h5>
            <p>{{ profile.age }}</p>
        {% empty %}
            <h1>No results, try again?</h1>
        {% endfor %}
    {% else %}
        {% for user in users %}
            <h5>{{ user.first_name }}</h5>
            <p>{{ user.profile.age }}</p>
        {% empty %}
            <h1>No results, try again?</h1>
        {% endfor %}
    {% endif %}

1 Ответ

0 голосов
/ 19 февраля 2019

Вы должны изменить свой шаблон, чтобы иметь только одну форму, которая выставляет как радиус, так и фильтры.Затем в своем методе записи используйте местоположение / радиус для создания набора запросов, который вы передаете в свой фильтр:

def post(self, request, *args, **kwargs):
    # default queryset, users is needed in context based on your get() method
    users = User.objects.exclude(username=request.user.username)
    queryset = Profile.objects.exclude(user=request.user)  
    if 'latitude' in request.POST and 'longitude' in request.POST:
        # code to store Location

    if 'radius' in request.POST:
        radius_km = request.POST.get('radius', 0)
        # reduce queryset by users within radius
        queryset = queryset.annotate(
            radius_sqr=pow(models.F('user__loc__latitude') -
            request.user.loc.latitude, 2) + pow(models.F('user__loc__longitude') -
            request.user.loc.longitude, 2)
            ).filter(
            radius_sqr__lte=pow(int(radius_km) / 9, 2)
            )
        messages.success(request, f'See the results of your search below.')

    filter = ProfileFilter(request.POST, queryset=queryset)
    return render(request, self.template_name, {'filter': filter, 'users': users})
...