From 93056cf524994e5a4d3a7a33d11cd01a28fa84b3 Mon Sep 17 00:00:00 2001 From: littlewolf Date: Tue, 3 Dec 2019 13:35:52 +0300 Subject: [PATCH] Add filter Add queryset Add settings --- _dockerfiles/db/Dockerfile | 2 +- apps/location/filters.py | 24 ++++++++++++++++++++++++ apps/location/models.py | 15 +++++++++++++++ apps/location/views/back.py | 4 ++++ docker-compose.mysql.yml | 1 + project/settings/local.py | 14 +++++++++++++- 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 apps/location/filters.py diff --git a/_dockerfiles/db/Dockerfile b/_dockerfiles/db/Dockerfile index 45c707d9..e8a9ded3 100644 --- a/_dockerfiles/db/Dockerfile +++ b/_dockerfiles/db/Dockerfile @@ -1,3 +1,3 @@ -FROM mdillon/postgis:9.5 +FROM mdillon/postgis:latest RUN localedef -i ru_RU -c -f UTF-8 -A /usr/share/locale/locale.alias ru_RU.UTF-8 ENV LANG ru_RU.utf8 diff --git a/apps/location/filters.py b/apps/location/filters.py new file mode 100644 index 00000000..5e95db44 --- /dev/null +++ b/apps/location/filters.py @@ -0,0 +1,24 @@ +from django.core.validators import EMPTY_VALUES +from django_filters import rest_framework as filters + +from location import models + + +class CityBackFilter(filters.FilterSet): + """Employee filter set.""" + + search = filters.CharFilter(method='search_by_name') + + class Meta: + """Meta class.""" + + model = models.City + fields = ( + 'search', + ) + + def search_by_name(self, queryset, name, value): + """Search by name or last name.""" + if value not in EMPTY_VALUES: + return queryset.search_by_name(value) + return queryset diff --git a/apps/location/models.py b/apps/location/models.py index 3f104644..32a6cf4f 100644 --- a/apps/location/models.py +++ b/apps/location/models.py @@ -5,6 +5,9 @@ from django.db.models.signals import post_save from django.db.transaction import on_commit from django.dispatch import receiver from django.utils.translation import gettext_lazy as _ +from functools import reduce +from typing import List + from translation.models import Language from utils.models import (ProjectBaseMixin, SVGImageMixin, TJSONField, @@ -92,6 +95,18 @@ class Region(models.Model): class CityQuerySet(models.QuerySet): """Extended queryset for City model.""" + def _generic_search(self, value, filter_fields_names: List[str]): + """Generic method for searching value in specified fields""" + filters = [ + {f'{field}__icontains': value} + for field in filter_fields_names + ] + return self.filter(reduce(lambda x, y: x | y, [models.Q(**i) for i in filters])) + + def search_by_name(self, value): + """Search by name or last_name.""" + return self._generic_search(value, ['name', 'code', 'postal_code']) + def by_country_code(self, code): """Return establishments by country code""" return self.filter(country__code=code) diff --git a/apps/location/views/back.py b/apps/location/views/back.py index 4d420154..8406dee3 100644 --- a/apps/location/views/back.py +++ b/apps/location/views/back.py @@ -9,6 +9,8 @@ from rest_framework.permissions import IsAuthenticatedOrReadOnly from django.shortcuts import get_object_or_404 from utils.serializers import ImageBaseSerializer +from location import filters + # Address @@ -31,6 +33,8 @@ class CityListCreateView(common.CityViewMixin, generics.ListCreateAPIView): """Create view for model City.""" serializer_class = serializers.CitySerializer permission_classes = [IsAuthenticatedOrReadOnly|IsCountryAdmin] + queryset = models.City.objects.all() + filter_class = filters.CityBackFilter class CityRUDView(common.CityViewMixin, generics.RetrieveUpdateDestroyAPIView): diff --git a/docker-compose.mysql.yml b/docker-compose.mysql.yml index a8900226..800a9644 100644 --- a/docker-compose.mysql.yml +++ b/docker-compose.mysql.yml @@ -29,6 +29,7 @@ services: - "5436:5432" volumes: - gm-db:/var/lib/postgresql/data/ + - .:/code elasticsearch: diff --git a/project/settings/local.py b/project/settings/local.py index 6a592a46..989af4ef 100644 --- a/project/settings/local.py +++ b/project/settings/local.py @@ -41,7 +41,19 @@ DATABASES.update({ 'PORT': 3306, 'NAME': 'dev', 'USER': 'dev', - 'PASSWORD': 'octosecret123'}}) + 'PASSWORD': 'octosecret123'}, + 'default': { + 'ENGINE': 'django.contrib.gis.db.backends.postgis', + 'NAME': os.environ.get('DB_NAME'), + 'USER': os.environ.get('DB_USERNAME'), + 'PASSWORD': os.environ.get('DB_PASSWORD'), + 'HOST': os.environ.get('DB_HOSTNAME'), + 'PORT': os.environ.get('DB_PORT'), + 'OPTIONS': { + 'options': '-c search_path=gm' + }, + }, +}) # LOGGING