Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…nto dev
  • Loading branch information
menma331 committed Mar 7, 2024
2 parents 0d8f807 + eca09be commit a5102f3
Show file tree
Hide file tree
Showing 17 changed files with 172 additions and 48 deletions.
10 changes: 10 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Dockerfile
.idea
.env.example
.gitignore
.github
*.md
.tox
LICENSE
Makefile
table.png
11 changes: 6 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=
EMAIL_USE_TLS=

REDIS_HOST=
REDIS_PORT=
REDIS_URL=

RABBIT_HOST=
RABBIT_PORT=
RABBIT_URL=

CELERY_TASK_TRACK_STARTED=
ACCEPT_CONTENT=
Expand All @@ -30,4 +28,7 @@ TIMEZONE=

YOOKASSA_SHOP_ID=
YOOKASSA_SECRET_KEY=
YOOKASSA_RETURN_URL=
YOOKASSA_RETURN_URL=

STATIC_FILES=/path/to/static/
MEDIA_FILES=/path/to/media/
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM python:3.11-alpine

WORKDIR /usr/src/app

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN pip install --upgrade pip
COPY ./requirements.txt .

RUN \
apk add --no-cache make && \
apk add --no-cache postgresql-libs && \
apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev && \
python3 -m pip install -r requirements.txt --no-cache-dir && \
apk --purge del .build-deps

COPY . .



12 changes: 5 additions & 7 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,27 +253,25 @@
# endregion -------------------------------------------------------------------------

# region ------------------------------- REDIS --------------------------------------
REDIS_HOST = env.str(var='REDIS_HOST', default='localhost')
REDIS_PORT = env.int(var='REDIS_PORT', default=6379)
REDIS_URL = env.str(var='REDIS_URL', default='redis://localhost:6379/0')
# Кэш с помощью => Redis.
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': f'redis://{REDIS_HOST}:{REDIS_PORT}',
'LOCATION': REDIS_URL,
}
}
# endregion -------------------------------------------------------------------------

# region ----------------------------- RABBITMQ -------------------------------------
RABBIT_HOST = env.str(var='RABBIT_HOST', default='localhost')
RABBIT_PORT = env.int(var='RABBIT_PORT', default=5672)
RABBIT_URL = env.str(var='RABBITMQ_URL', default='amqp://guest:guest@localhost:5672')
# endregion -------------------------------------------------------------------------

# region ------------------------------- CELERY -------------------------------------
# Использование брокера сообщений для Celery на базе RabbitMQ.
CELERY_BROKER_URL = f'amqp://guest:guest@{RABBIT_HOST}:{RABBIT_PORT}'
CELERY_BROKER_URL = RABBIT_URL
# Использование БД для Celery на базе Redis.
CELERY_RESULT_BACKEND = f'redis://{REDIS_HOST}:{REDIS_PORT}'
CELERY_RESULT_BACKEND = REDIS_URL
CELERY_TASK_TRACK_STARTED = env.bool(var='CELERY_TASK_TRACK_STARTED', default=False)
CELERY_TASK_TIME_LIMIT = 30 * 60
accept_content = [env.str(var='ACCEPT_CONTENT', default='application/json')]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from __future__ import annotations

from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Union

from rest_framework.permissions import IsAuthenticated

from delivers.models.couriers import Courier
from delivers.models.delivers import Delivery

if TYPE_CHECKING:
from rest_framework.request import Request
from delivers.models.delivers import Delivery
from delivers.views.delivery import DeliveryViewSet
from delivers.views.delivers import DeliveryViewSet
from delivers.views.couriers import CourierViewSet


class IsCourierOrStaff(IsAuthenticated):
Expand All @@ -19,7 +22,10 @@ class IsCourierOrStaff(IsAuthenticated):

def has_permission(self, request: Request, view: DeliveryViewSet):
"""Проверка пользователя, на права Курьера либо Персонала."""
if request.user.role == request.user.Role.COURIER:
if (
super().has_permission(request, view) and
request.user.role == request.user.Role.COURIER
):
return True
return bool(request.user.is_staff or request.user.is_superuser)

Expand All @@ -37,11 +43,13 @@ class IsCurrentCourierOrStaff(IsAuthenticated):
def has_object_permission(
self,
request: Request,
view: DeliveryViewSet,
obj: Delivery
view: Union[DeliveryViewSet, CourierViewSet],
obj: Union[Delivery, Courier],
):
if request.user.is_staff or request.user.is_superuser:
return True
if request.user == obj.courier.user:
if isinstance(obj, Delivery) and request.user == obj.courier.user:
return True
if isinstance(obj, Courier) and request.user == obj.user:
return True
return False
3 changes: 3 additions & 0 deletions delivers/serializers/api/couriers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,13 @@ class Meta:
class CourierCreateSerializer(serializers.ModelSerializer):
"""Сериализатор создания курьера."""

user = serializers.HiddenField(default=serializers.CurrentUserDefault())

class Meta:
model = Courier
fields = (
'id',
'user',
'name',
'phone_number',
'email',
Expand Down
4 changes: 2 additions & 2 deletions delivers/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
from rest_framework.routers import DefaultRouter

from .views import couriers
from .views import delivery
from .views import delivers
from .views import vehicle

router = DefaultRouter()

router.register(prefix='couriers', viewset=couriers.CourierViewSet, basename='couriers')
router.register(prefix='delivery', viewset=delivery.DeliveryViewSet, basename='delivery')
router.register(prefix='delivery', viewset=delivers.DeliveryViewSet, basename='delivers')
router.register(prefix='vehicle', viewset=vehicle.VehicleViewSet, basename='vehicle')

urlpatterns = []
Expand Down
14 changes: 10 additions & 4 deletions delivers/views/couriers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema_view, extend_schema
from rest_framework import permissions
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework_simplejwt import authentication as jwt_authentication

from common.views.mixins import CRUDListViewSet
from ..models.couriers import Courier
from ..permission import couriers as permissions_cour
from ..serializers.api import couriers as couriers_s


Expand Down Expand Up @@ -42,12 +43,17 @@
)
class CourierViewSet(CRUDListViewSet):
"""Представление курьера."""
queryset = Courier.objects.all()

permission_classes = (permissions.AllowAny,)
authentication_classes = (jwt_authentication.JWTAuthentication,)

queryset = Courier.objects.all()
serializer_class = couriers_s.CourierListSerializer
permission_classes = (permissions_cour.IsCourierOrStaff,)
multi_permission_classes = {
'partial_update': (permissions_cour.IsCurrentCourierOrStaff,),
'destroy': (permissions_cour.IsCurrentCourierOrStaff,),
}

serializer_class = couriers_s.CourierListSerializer
multi_serializer_class = {
'list': couriers_s.CourierListSerializer,
'retrieve': couriers_s.CourierRetrieveSerializer,
Expand Down
11 changes: 4 additions & 7 deletions delivers/views/delivery.py → delivers/views/delivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from common.views.mixins import CRUDListViewSet
from ..models.delivers import Delivery
from ..permission import delivers as permissions_del
from ..permission import couriers as permissions_cour
from ..serializers.api import delivery as delivery_s


Expand Down Expand Up @@ -35,13 +35,10 @@ class DeliveryViewSet(CRUDListViewSet):

authentication_classes = (jwt_authentication.JWTAuthentication,)

permission_classes = (permissions_del.IsCourierOrStaff,)
permission_classes = (permissions_cour.IsCourierOrStaff,)
multi_permission_classes = {
'create': (permissions_del.IsCourierOrStaff,),
'retrieve': (permissions_del.IsCourierOrStaff,),
'partial_update': (permissions_del.IsCurrentCourierOrStaff,),
'destroy': (permissions_del.IsCurrentCourierOrStaff,),
'list': (permissions_del.IsCourierOrStaff,)
'partial_update': (permissions_cour.IsCurrentCourierOrStaff,),
'destroy': (permissions_cour.IsCurrentCourierOrStaff,),
}

serializer_class = delivery_s.DeliveryListSerializer
Expand Down
22 changes: 9 additions & 13 deletions delivers/views/vehicle.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from drf_spectacular.utils import extend_schema_view, extend_schema
from rest_framework import permissions
from rest_framework_simplejwt import authentication as jwt_authentication

from common.views.mixins import CRUDListViewSet
from delivers.models.couriers import Vehicle
from delivers.serializers.api import vehicle as vehicle_s
from ..models.couriers import Vehicle
from ..permission import couriers as permissions_cour
from ..serializers.api import vehicle as vehicle_s


@extend_schema_view(
Expand All @@ -30,27 +31,22 @@
)
class VehicleViewSet(CRUDListViewSet):
"""Представление транспорта."""

queryset = Vehicle.objects.all()

permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (jwt_authentication.JWTAuthentication,)

permission_classes = (permissions_cour.IsCourierOrStaff,)
multi_permission_classes = {
'create': (permissions.IsAdminUser,),
'retrieve': (permissions.AllowAny,),
'partial_update': (permissions.IsAdminUser,),
'destroy': (permissions.IsAdminUser,),
'list': (permissions.AllowAny,)
'partial_update': (permissions_cour.IsCurrentCourierOrStaff,),
'destroy': (permissions_cour.IsCurrentCourierOrStaff,),
}

http_method_names = ('get', 'patch', 'post', 'delete')

serializer_class = vehicle_s.VehicleListSerializer

multi_serializer_class = {
'create': vehicle_s.VehicleCreateSerializer,
'retrieve': vehicle_s.VehicleRetrieveSerializer,
'partial_update': vehicle_s.VehicleUpdateSerializer,
'destroy': vehicle_s.VehicleDeleteSerializer,
'list': vehicle_s.VehicleListSerializer
}
http_method_names = ('get', 'patch', 'post', 'delete')
71 changes: 71 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
version: '3.11'

services:

web:
build: ./
command: python manage.py runserver 0.0.0.0:8000
container_name: web-online-store
volumes:
- ./:/usr/src/app/
- /var/www/back/static/:/usr/src/app/static/
- /var/www/back/media/:/usr/src/app/media/
ports:
- "8000:8000"
env_file:
- ./.env
depends_on:
- db
- redis
- rabbitmq
- celery
- celery-beat

db:
image: postgres:14-alpine
container_name: db-store
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=${PG_USER}
- POSTGRES_PASSWORD=${PG_PASSWORD}
- POSTGRES_DB=${PG_DATABASE}

redis:
image: redis:latest
container_name: redis-store

rabbitmq:
image: rabbitmq:latest
container_name: rabbitmq-store

celery:
restart: always
build:
context: ./
command: celery -A online_store worker -l INFO
volumes:
- ./:/usr/src/app/
container_name: celery-store
depends_on:
- db
- redis
- rabbitmq
- web

celery-beat:
restart: always
build:
context: ./
command: celery -A backend beat -l info
volumes:
- ./:/usr/src/app/
container_name: celery-beat-store
depends_on:
- db
- redis
- rabbitmq
- web

volumes:
postgres_data:
2 changes: 2 additions & 0 deletions orders/permissions/orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def has_object_permission(
Проверка пользователя на доступ к конкретному заказу.
Если это персонал, то доступ на изменение товара разрешит.
"""
if request.user.is_anonymous:
return False
if request.user.is_staff or request.user.is_superuser:
return True
if request.user == obj.user:
Expand Down
2 changes: 2 additions & 0 deletions products/permissions/categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def has_permission(self, request: Request, view: CategoryView) -> bool:
"""
if request.method in SAFE_METHODS:
return True
if request.user.is_anonymous:
return False
return bool(
request.user.is_authenticated and
request.user.is_staff or
Expand Down
2 changes: 2 additions & 0 deletions products/permissions/products.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def has_object_permission(
Проверка поставщика на доступ к конкретному товару.
Если это персонал, то доступ на изменение товара разрешит.
"""
if not request.user.is_authenticated:
return False
if request.user.is_staff or request.user.is_superuser:
return True
if request.user == obj.provider.user:
Expand Down
5 changes: 5 additions & 0 deletions products/permissions/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ def has_permission(
if request.method in SAFE_METHODS:
return True

if request.user.is_anonymous:
return False

if request.user.role == request.user.Role.PROVIDER:
return bool(request.user and request.user.is_authenticated)

Expand Down Expand Up @@ -70,6 +73,8 @@ def has_object_permission(
Проверка пользователя на доступ к конкретному Поставщику.
Если это персонал, то доступ на изменение модели Поставщика разрешит.
"""
if not request.user.is_authenticated and request.user.is_anonymous:
return False
if request.user.is_staff or request.user.is_superuser:
return True
if request.user == obj.user:
Expand Down
Loading

0 comments on commit a5102f3

Please sign in to comment.