mirror of
				https://github.com/more-tech4-magnum-opus/backend.git
				synced 2025-10-31 07:47:32 +03:00 
			
		
		
		
	added event crud
This commit is contained in:
		
							parent
							
								
									dada351290
								
							
						
					
					
						commit
						7172920c07
					
				|  | @ -1,6 +1,17 @@ | |||
| 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): | ||||
|     """ | ||||
|     Checks if request user is an admin or hr | ||||
|  | @ -14,7 +25,7 @@ class IsManager(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): | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| from django.urls import path, include | ||||
| from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView | ||||
| 
 | ||||
| from events.api.views import ListCreateEventApi, RetireUpdateDeleteEventApi | ||||
| from marketplace.api.views import ListCreateProductApi, RetireUpdateDestroyProductApi | ||||
| from users.api.views import ( | ||||
|     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( | ||||
|         "marketplace/", | ||||
|         include( | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ REST_FRAMEWORK = { | |||
|         "rest_framework_simplejwt.authentication.JWTAuthentication", | ||||
|     ), | ||||
|     "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.AllowAny",), | ||||
|     "DATETIME_FORMAT": "%Y-%m-%dT%H:%M:%S.%fZ", | ||||
| } | ||||
| 
 | ||||
| # STATIC | ||||
|  |  | |||
							
								
								
									
										0
									
								
								app/events/api/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								app/events/api/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										32
									
								
								app/events/api/serializers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/events/api/serializers.py
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										34
									
								
								app/events/api/views.py
									
									
									
									
									
										Normal 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() | ||||
|  | @ -2,5 +2,8 @@ from django.apps import AppConfig | |||
| 
 | ||||
| 
 | ||||
| class EventsConfig(AppConfig): | ||||
|     default_auto_field = 'django.db.models.BigAutoField' | ||||
|     name = 'events' | ||||
|     default_auto_field = "django.db.models.BigAutoField" | ||||
|     name = "events" | ||||
| 
 | ||||
|     def ready(self): | ||||
|         import events.signals | ||||
|  |  | |||
							
								
								
									
										45
									
								
								app/events/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/events/migrations/0001_initial.py
									
									
									
									
									
										Normal 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)), | ||||
|             ], | ||||
|         ), | ||||
|     ] | ||||
|  | @ -1,3 +1,36 @@ | |||
| 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
									
								
							
							
						
						
									
										13
									
								
								app/events/services.py
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										41
									
								
								app/events/signals.py
									
									
									
									
									
										Normal 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"]) | ||||
|  | @ -1,3 +0,0 @@ | |||
| from django.shortcuts import render | ||||
| 
 | ||||
| # Create your views here. | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user