Filter offers
This commit is contained in:
parent
cad77f6a4a
commit
1cabae10e8
|
@ -1,5 +1,6 @@
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth.forms import UserCreationForm
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
from friendly_captcha.fields import FrcCaptchaField
|
from friendly_captcha.fields import FrcCaptchaField
|
||||||
|
|
||||||
from .models import Offer, PflaenzliUser
|
from .models import Offer, PflaenzliUser
|
||||||
|
@ -17,3 +18,12 @@ class RegistrationForm(UserCreationForm):
|
||||||
fields = UserCreationForm.Meta.fields + ('email', 'zipcode',)
|
fields = UserCreationForm.Meta.fields + ('email', 'zipcode',)
|
||||||
|
|
||||||
captcha = FrcCaptchaField()
|
captcha = FrcCaptchaField()
|
||||||
|
|
||||||
|
|
||||||
|
class FilterForm(forms.Form):
|
||||||
|
text = forms.CharField(max_length=128, required=False, label=mark_safe(
|
||||||
|
'<i class="fa-solid fa-magnifying-glass"></i> Search'))
|
||||||
|
zipcode = forms.CharField(max_length=4, required=False, label=mark_safe(
|
||||||
|
'<i class="fa-solid fa-location-dot"></i> Zipcode'))
|
||||||
|
distance = forms.IntegerField(required=False, label=mark_safe(
|
||||||
|
'<i class="fa-solid fa-signs-post"></i> Distance (km)'))
|
||||||
|
|
|
@ -1,10 +1,29 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
{% block title %}Offers{% endblock %}
|
{% block title %}Offers{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Offers</h1>
|
<h1 class="mt-3">
|
||||||
|
Offers
|
||||||
|
<button class="btn btn-pfl"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#filterCollapse"
|
||||||
|
aria-expanded="true"
|
||||||
|
aria-controls="filterCollapse">
|
||||||
|
<i class="fa-solid fa-filter"></i> Filter
|
||||||
|
</button>
|
||||||
|
</h1>
|
||||||
|
<form method="post"
|
||||||
|
enctype="multipart/form-data"
|
||||||
|
class="collapse"
|
||||||
|
id="filterCollapse">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-pfl">Filter</button>
|
||||||
|
</form>
|
||||||
{% if offers %}
|
{% if offers %}
|
||||||
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-3 mb-3 row-gap-5">
|
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-3 mt-3 mb-3 row-gap-5">
|
||||||
{% for offer in offers %}
|
{% for offer in offers %}
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card h-100 p-0">
|
<div class="card h-100 p-0">
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from geopy.distance import distance
|
from geopy.distance import distance
|
||||||
import os
|
import os
|
||||||
from pandas import read_pickle
|
from pandas import read_pickle
|
||||||
|
from django.db.models import F, Func
|
||||||
|
|
||||||
path = os.path.dirname(os.path.abspath(__file__))
|
path = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ df = read_pickle(os.path.join(path, 'plz.pkl'))
|
||||||
|
|
||||||
def calculate_distance(zip_1, zip_2):
|
def calculate_distance(zip_1, zip_2):
|
||||||
if zip_1 == zip_2:
|
if zip_1 == zip_2:
|
||||||
return None
|
return 0
|
||||||
|
|
||||||
zip_1_coords = tuple(df[df.index == zip_1].values)
|
zip_1_coords = tuple(df[df.index == zip_1].values)
|
||||||
zip_2_coords = tuple(df[df.index == zip_2].values)
|
zip_2_coords = tuple(df[df.index == zip_2].values)
|
||||||
|
@ -17,3 +18,12 @@ def calculate_distance(zip_1, zip_2):
|
||||||
dist = round(distance((zip_1_coords), (zip_2_coords)).kilometers)
|
dist = round(distance((zip_1_coords), (zip_2_coords)).kilometers)
|
||||||
|
|
||||||
return None if dist > 400 else dist
|
return None if dist > 400 else dist
|
||||||
|
|
||||||
|
|
||||||
|
def filter_by_distance(qs, filter_zipcode, max_dist):
|
||||||
|
filtered_offers = []
|
||||||
|
for offer in qs:
|
||||||
|
d = calculate_distance(int(offer.zipcode), int(filter_zipcode))
|
||||||
|
if d is not None and d <= max_dist:
|
||||||
|
filtered_offers.append(offer)
|
||||||
|
return filtered_offers
|
||||||
|
|
|
@ -5,17 +5,25 @@ from django.contrib.auth import login
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.http import HttpResponseForbidden
|
from django.http import HttpResponseForbidden
|
||||||
|
|
||||||
from .forms import CreateOfferForm, RegistrationForm
|
from .forms import CreateOfferForm, RegistrationForm, FilterForm
|
||||||
|
|
||||||
from .models import PflaenzliUser, Offer, Wish
|
from .models import PflaenzliUser, Offer, Wish
|
||||||
from .mail import send_offer_email
|
from .mail import send_offer_email
|
||||||
from .upload import generate_unique_filename
|
from .upload import generate_unique_filename
|
||||||
from .utils.distance import calculate_distance
|
from .utils.distance import calculate_distance, filter_by_distance
|
||||||
|
|
||||||
|
|
||||||
def list_offers(request, filters=None):
|
def list_offers(request, filters=None):
|
||||||
offers = Offer.objects.all()
|
offers = Offer.objects.all()
|
||||||
return render(request, "offer/search.html", {"offers": offers})
|
|
||||||
|
if request.method == "POST":
|
||||||
|
form = FilterForm(request.POST, request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
offers = filter_offers(offers, form)
|
||||||
|
else:
|
||||||
|
form = FilterForm()
|
||||||
|
|
||||||
|
return render(request, "offer/search.html", {"offers": offers, "form": form})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -114,3 +122,16 @@ def register_user(request):
|
||||||
form = RegistrationForm()
|
form = RegistrationForm()
|
||||||
|
|
||||||
return render(request, "basic_form.html", {"form": form, "button_label": "Register", "title": "Registeration"})
|
return render(request, "basic_form.html", {"form": form, "button_label": "Register", "title": "Registeration"})
|
||||||
|
|
||||||
|
|
||||||
|
def filter_offers(offers, form):
|
||||||
|
if form.cleaned_data['text']:
|
||||||
|
offers = offers.filter(title__icontains=form.cleaned_data['text'])
|
||||||
|
|
||||||
|
if form.cleaned_data['zipcode']:
|
||||||
|
if form.cleaned_data['distance']:
|
||||||
|
offers = filter_by_distance(offers, form.cleaned_data['zipcode'], form.cleaned_data['distance'])
|
||||||
|
else:
|
||||||
|
offers = offers.filter(zipcode=int(form.cleaned_data['zipcode']))
|
||||||
|
|
||||||
|
return offers
|
||||||
|
|
Loading…
Reference in a new issue