added event crud

This commit is contained in:
Alexander Karpov 2022-10-08 19:31:01 +03:00
parent dada351290
commit 7172920c07
12 changed files with 231 additions and 7 deletions

View File

@ -1,6 +1,17 @@
from rest_framework import permissions from rest_framework import permissions
class IsWorker(permissions.BasePermission):
"""
Checks if request user is worker(not hr or admin)
"""
def has_permission(self, request, view):
if request.method in permissions.SAFE_METHODS:
return True
return not request.user.is_manager
class IsManager(permissions.BasePermission): class IsManager(permissions.BasePermission):
""" """
Checks if request user is an admin or hr Checks if request user is an admin or hr
@ -14,7 +25,7 @@ class IsManager(permissions.BasePermission):
class IsAdmin(permissions.BasePermission): class IsAdmin(permissions.BasePermission):
""" """
Checks if request user is an admin or hr Checks if request user is an admin
""" """
def has_permission(self, request, view): def has_permission(self, request, view):

View File

@ -1,6 +1,7 @@
from django.urls import path, include from django.urls import path, include
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from events.api.views import ListCreateEventApi, RetireUpdateDeleteEventApi
from marketplace.api.views import ListCreateProductApi, RetireUpdateDestroyProductApi from marketplace.api.views import ListCreateProductApi, RetireUpdateDestroyProductApi
from users.api.views import ( from users.api.views import (
ListCreateUserApi, ListCreateUserApi,
@ -23,6 +24,19 @@ urlpatterns = [
] ]
), ),
), ),
path(
"events/",
include(
[
path("", ListCreateEventApi.as_view(), name="list_create_event"),
path(
"<str:slug>",
RetireUpdateDeleteEventApi.as_view(),
name="get_update_delete_event",
),
]
),
),
path( path(
"marketplace/", "marketplace/",
include( include(

View File

@ -39,6 +39,7 @@ REST_FRAMEWORK = {
"rest_framework_simplejwt.authentication.JWTAuthentication", "rest_framework_simplejwt.authentication.JWTAuthentication",
), ),
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.AllowAny",), "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.AllowAny",),
"DATETIME_FORMAT": "%Y-%m-%dT%H:%M:%S.%fZ",
} }
# STATIC # STATIC

View File

View File

@ -0,0 +1,32 @@
from rest_framework import serializers
from events.models import Event
from users.api.serializers import UserSerializer
class EventSerializer(serializers.ModelSerializer):
creator = UserSerializer(many=False, read_only=True)
class Meta:
model = Event
fields = [
"name",
"about",
"slug",
"creator",
"starts",
"image",
"planning",
"attended",
]
extra_kwargs = {
"slug": {"read_only": True},
"creator": {"read_only": True},
"planning": {"read_only": True},
"attended": {"read_only": True},
}
def create(self, validated_data):
return Event.objects.create(
**validated_data, creator=self.context["request"].user
)

34
app/events/api/views.py Normal file
View File

@ -0,0 +1,34 @@
from datetime import datetime
import pytz
from rest_framework import generics
from rest_framework.generics import get_object_or_404
from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework.permissions import IsAuthenticated
from common.permissions import IsManager
from events.api.serializers import EventSerializer
from events.models import Event
class ListCreateEventApi(generics.ListCreateAPIView):
serializer_class = EventSerializer
parser_classes = [FormParser, MultiPartParser]
permission_classes = [IsAuthenticated, IsManager]
queryset = Event.objects.filter(
starts__gte=datetime.now(pytz.timezone("Europe/Moscow"))
)
class RetireUpdateDeleteEventApi(generics.RetrieveUpdateDestroyAPIView):
def get_object(self):
event = get_object_or_404(
Event,
slug=self.request.parser_context["kwargs"]["slug"],
)
return event
serializer_class = EventSerializer
parser_classes = [FormParser, MultiPartParser]
permission_classes = [IsAuthenticated, IsManager]
queryset = Event.objects.all()

View File

@ -2,5 +2,8 @@ from django.apps import AppConfig
class EventsConfig(AppConfig): class EventsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = "django.db.models.BigAutoField"
name = 'events' name = "events"
def ready(self):
import events.signals

View File

@ -0,0 +1,45 @@
# Generated by Django 4.0.8 on 2022-10-08 15:44
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Event',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('slug', models.SlugField(max_length=8)),
('about', models.TextField(blank=True)),
('starts', models.DateTimeField()),
('image', models.ImageField(blank=True, upload_to='uploads/')),
('image_cropped', models.ImageField(blank=True, upload_to='cropped/')),
('planning', models.IntegerField(default=0)),
('attended', models.IntegerField(default=0)),
('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events_created', to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ['-starts'],
},
),
migrations.CreateModel(
name='EventAttendance',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('token', models.CharField(max_length=128, unique=True)),
('attended', models.BooleanField(default=False)),
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='people', to='events.event')),
('worker', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -1,3 +1,36 @@
from django.db import models from django.db import models
# Create your models here. from users.models import User
class Event(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(max_length=8)
about = models.TextField(blank=True)
creator = models.ForeignKey(
User, related_name="events_created", on_delete=models.CASCADE
)
starts = models.DateTimeField(blank=False)
image = models.ImageField(upload_to="uploads/", blank=True)
image_cropped = models.ImageField(upload_to="cropped/", blank=True)
planning = models.IntegerField(default=0)
attended = models.IntegerField(default=0)
def __str__(self):
return self.name
class Meta:
ordering = ["-starts"]
class EventAttendance(models.Model):
event = models.ForeignKey(Event, related_name="people", on_delete=models.CASCADE)
worker = models.ForeignKey(User, related_name="events", on_delete=models.CASCADE)
token = models.CharField(blank=False, unique=True, max_length=128)
attended = models.BooleanField(default=False)
def __str__(self):
return f"{self.worker.name} attendance on {self.event.name}"

13
app/events/services.py Normal file
View File

@ -0,0 +1,13 @@
from rest_framework.generics import get_object_or_404
from events.models import EventAttendance
def submit_attendance(token: str):
attendance = get_object_or_404(EventAttendance, token=token)
if not attendance.attended:
attendance.attended = True
attendance.save()
attendance.event.attended += 1
attendance.event.save()

41
app/events/signals.py Normal file
View File

@ -0,0 +1,41 @@
from django.core.files import File
from django.db.models.signals import pre_save, post_delete, post_save
from django.dispatch import receiver
from utils.file import crop_image
from utils.generators import generate_charset
from .models import EventAttendance, Event
@receiver(pre_save, sender=EventAttendance)
def create_attendance(sender, instance, **kwargs):
token = generate_charset(25)
while EventAttendance.objects.filter(token=token).exists():
token = generate_charset(25)
instance.token = token
instance.event.planning += 1
instance.event.save(update_fileds=["planning"])
@receiver(post_save, sender=Event)
def process_event(sender, instance, created, **kwargs):
if created:
slug = generate_charset(5)
while Event.objects.filter(slug=slug).exists():
slug = generate_charset(5)
instance.slug = slug
instance.save(update_fields=["slug"])
if instance.image and kwargs["update_fields"] is None:
instance.image_cropped = File(
crop_image(instance.image.path, cut_to=(250, 250)),
name=instance.image.path.split(".")[0].split("/")[-1] + ".png",
)
instance.save(update_fields=["image_cropped"])
@receiver(post_delete, sender=EventAttendance)
def delete_attendance(sender, instance, **kwargs):
instance.event.planning -= 1
instance.event.save(update_fileds=["planning"])

View File

@ -1,3 +0,0 @@
from django.shortcuts import render
# Create your views here.