Filter um Kategorie erweitern

This commit is contained in:
Daniel Grams 2020-10-03 09:55:07 +02:00
parent 7ffb790f7c
commit 73bb9576bc
10 changed files with 126 additions and 58 deletions

22
forms/event_date.py Normal file
View File

@ -0,0 +1,22 @@
from flask_babelex import lazy_gettext, gettext
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from wtforms import SelectMultipleField, FieldList, RadioField, DateTimeField, StringField, SubmitField, TextAreaField, SelectField, BooleanField, IntegerField, FormField
from wtforms.fields.html5 import DateTimeLocalField, EmailField
from wtforms.validators import DataRequired, Optional
from wtforms.widgets import html_params, HTMLString
from models import EventContact, EventPlace, EventTargetGroupOrigin, EventAttendanceMode, EventStatus, Location, EventOrganizer, EventRejectionReason, EventReviewStatus
from .common import event_rating_choices
from .widgets import CustomDateField
class FindEventDateForm(FlaskForm):
class Meta:
csrf = False
date_from = CustomDateField(lazy_gettext('From'), validators=[Optional()])
date_to = CustomDateField(lazy_gettext('to'), validators=[Optional()])
keyword = StringField(lazy_gettext('Keyword'), validators=[Optional()])
category_id = SelectField(lazy_gettext('Category'), validators=[Optional()], coerce=int)
submit = SubmitField(lazy_gettext("Find"))

View File

@ -3,6 +3,7 @@ from wtforms.widgets import html_params, HTMLString, ListWidget, CheckboxInput
import pytz
from datetime import datetime
from flask_babelex import to_user_timezone
from dateutils import berlin_tz
class MultiCheckboxField(SelectMultipleField):
widget = ListWidget(prefix_label=False)
@ -15,8 +16,6 @@ def create_option_string(count, value):
result = result + '<option value="%02d"%s>%02d</option>' % (i, selected, i)
return result
berlin_tz = pytz.timezone('Europe/Berlin')
class CustomDateTimeWidget:
def __call__(self, field, **kwargs):
id = kwargs.pop('id', field.id)
@ -50,3 +49,30 @@ class CustomDateTimeField(DateTimeField):
self.data = berlin_tz.localize(date_time)
except:
raise ValueError('Not a valid datetime value. Looking for YYYY-MM-DD HH:mm.')
class CustomDateWidget:
def __call__(self, field, **kwargs):
id = kwargs.pop('id', field.id)
date = ''
if field.data:
date_value = to_user_timezone(field.data)
date = date_value.strftime("%Y-%m-%d")
date_params = html_params(name=field.name, id=id, value=date, **kwargs)
return HTMLString('<input type="text" {}/>'.format(date_params))
class CustomDateField(DateTimeField):
widget = CustomDateWidget()
def process_formdata(self, valuelist):
if valuelist:
try:
date_str = valuelist[0]
if not date_str:
self.data = None
return
date = datetime.strptime(date_str, "%Y-%m-%d")
self.data = berlin_tz.localize(date)
except:
raise ValueError('Not a valid date value. Looking for YYYY-MM-DD.')

View File

@ -27,6 +27,13 @@ def get_event_dates_query(params):
like_keyword = '%' + params.keyword + '%'
event_filter = and_(event_filter, or_(Event.name.ilike(like_keyword), Event.description.ilike(like_keyword), Event.tags.ilike(like_keyword)))
if params.category_id:
if type(params.category_id) is list:
category_ids = params.category_id
else:
category_ids = [params.category_id]
event_filter = and_(event_filter, Event.category_id.in_(category_ids))
if params.latitude and params.longitude and params.distance:
point = 'POINT({} {})'.format(params.longitude, params.latitude)
event_filter = and_(event_filter, func.ST_DistanceSphere(Location.coordinate, point) <= params.distance)

View File

@ -14,6 +14,7 @@ class EventSearchParams(object):
self.latitude = None
self.longitude = None
self.distance = None
self.category_id = None
@property
def date_from(self):
@ -72,3 +73,6 @@ class EventSearchParams(object):
if "distance" in request.args:
self.distance = request.args['distance']
if "category_id" in request.args:
self.category_id = request.args.getlist('category_id')

View File

@ -573,4 +573,38 @@ $( function() {
<td>{{ subfield.label(class="form-check-label") }}</td>
</div>
{% endfor %}
{% endmacro %}
{% macro render_event_dates_filter_form(form) %}
<form action="" class="form-inline mb-4" method="GET" autocomplete="off">
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ form.date_from.label() }}</span>
</div>
{{ form.date_from(class="form-control datepicker")|safe }}
</div>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ form.date_to.label() }}</span>
</div>
{{ form.date_to(class="form-control datepicker")|safe }}
</div>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ form.category_id.label() }}</span>
</div>
{{ form.category_id(class="form-control")|safe }}
</div>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ form.keyword.label() }}</span>
</div>
{{ form.keyword(class="form-control")|safe }}
</div>
<button type="submit" class="btn btn-primary mb-2">{{ _('Find') }}</button>
</form>
{% endmacro %}

View File

@ -1,5 +1,5 @@
{% extends "layout.html" %}
{% from "_macros.html" import render_pagination, render_event_status_pill, render_place, render_events_sub_menu %}
{% from "_macros.html" import render_event_dates_filter_form, render_pagination, render_event_status_pill, render_place, render_events_sub_menu %}
{% block title %}
{{ _('Event Dates') }}
{% endblock %}
@ -7,31 +7,7 @@
<h1>{{ _('Event Dates') }}</h1>
<form action="{{ url_for('event_dates') }}" class="form-inline mb-4" method="GET" autocomplete="off">
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ _('From') }}</span>
</div>
<input type="text" id="date_from" name="date_from" value="{{ params.date_from_str }}" class="form-control datepicker" />
</div>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ _('to') }}</span>
</div>
<input type="text" id="date_to" name="date_to" value="{{ params.date_to_str }}" class="form-control datepicker" />
</div>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ _('Keyword') }}</span>
</div>
<input type="text" name="keyword" value="{{ (params.keyword or '') }}" class="form-control" />
</div>
<button type="submit" class="btn btn-primary mb-2">{{ _('Find') }}</button>
</form>
{{ render_event_dates_filter_form(form) }}
{% for date in dates %}
<div class="card mb-3" style="max-width: 768px;">

View File

@ -1,5 +1,5 @@
{% extends "layout.html" %}
{% from "_macros.html" import render_pagination, render_event_status_pill, render_event_status_pill, render_place, render_events_sub_menu %}
{% from "_macros.html" import render_event_dates_filter_form, render_pagination, render_event_status_pill, render_event_status_pill, render_place, render_events_sub_menu %}
{% block title %}
{{ _('Widget') }}
{% endblock %}
@ -10,31 +10,7 @@
{% endblock %}
{% block content %}
<form action="" class="form-inline mb-4" method="GET" autocomplete="off">
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ _('From') }}</span>
</div>
<input type="text" id="date_from" name="date_from" value="{{ params.date_from_str }}" class="form-control datepicker" />
</div>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ _('to') }}</span>
</div>
<input type="text" id="date_to" name="date_to" value="{{ params.date_to_str }}" class="form-control datepicker" />
</div>
<div class="input-group mb-2 mr-sm-2">
<div class="input-group-prepend">
<span class="input-group-text">{{ _('Keyword') }}</span>
</div>
<input type="text" name="keyword" value="{{ (params.keyword or '') }}" class="form-control" />
</div>
<button type="submit" class="btn btn-primary mb-2">{{ _('Find') }}</button>
</form>
{{ render_event_dates_filter_form(form) }}
{% for date in dates %}

View File

@ -158,9 +158,12 @@ def event_create_base(admin_unit, organizer_id=0):
flash_errors(form)
return render_template('event/create.html', form=form)
def get_event_category_choices():
return sorted([(c.id, get_event_category_name(c)) for c in EventCategory.query.all()], key=lambda category: category[1])
def prepare_event_form(form, admin_unit):
form.organizer_id.choices = [(o.id, o.name) for o in EventOrganizer.query.filter(EventOrganizer.admin_unit_id == admin_unit.id).order_by(func.lower(EventOrganizer.name))]
form.category_id.choices = sorted([(c.id, get_event_category_name(c)) for c in EventCategory.query.all()], key=lambda category: category[1])
form.category_id.choices = get_event_category_choices()
if form.organizer_id.data:
places = get_event_places(form.organizer_id.data)

View File

@ -10,16 +10,28 @@ import json
from jsonld import get_sd_for_event_date, DateTimeEncoder
from services.event_search import EventSearchParams
from services.event import get_event_dates_query
from forms.event_date import FindEventDateForm
from .event import get_event_category_choices
def prepare_event_date_form(form):
form.category_id.choices = get_event_category_choices()
form.category_id.choices.insert(0, (0, ''))
@app.route("/eventdates")
def event_dates():
params = EventSearchParams()
params.set_default_date_range()
params.load_from_request()
form = FindEventDateForm(formdata=request.args, obj=params)
prepare_event_date_form(form)
if form.validate():
form.populate_obj(params)
dates = get_event_dates_query(params).paginate()
return render_template('event_date/list.html',
form=form,
params=params,
dates=dates.items,
pagination=get_pagination_urls(dates))

View File

@ -9,6 +9,8 @@ from services.event_search import EventSearchParams
from .utils import get_pagination_urls
import json
from jsonld import DateTimeEncoder, get_sd_for_event_date
from forms.event_date import FindEventDateForm
from .event_date import prepare_event_date_form
@app.route("/<string:au_short_name>/widget/eventdates")
def widget_event_dates(au_short_name):
@ -16,12 +18,18 @@ def widget_event_dates(au_short_name):
params = EventSearchParams()
params.set_default_date_range()
params.load_from_request()
params.admin_unit_id = admin_unit.id
form = FindEventDateForm(formdata=request.args, obj=params)
prepare_event_date_form(form)
if form.validate():
form.populate_obj(params)
params.admin_unit_id = admin_unit.id
dates = get_event_dates_query(params).paginate()
return render_template('widget/event_date/list.html',
form=form,
params=params,
dates=dates.items,
pagination=get_pagination_urls(dates, au_short_name=au_short_name))