diff --git a/backend/project/api/core/__init__.py b/backend/project/api/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/project/api/core/apps.py b/backend/project/api/core/apps.py new file mode 100644 index 0000000..15adafc --- /dev/null +++ b/backend/project/api/core/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CoreConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "api.core" diff --git a/backend/project/api/core/migrations/__init__.py b/backend/project/api/core/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/project/api/core/models.py b/backend/project/api/core/models.py new file mode 100644 index 0000000..3e15729 --- /dev/null +++ b/backend/project/api/core/models.py @@ -0,0 +1,9 @@ +from django.db import models + + +class BaseModel(models.Model): + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + abstract = True diff --git a/backend/project/api/events/__init__.py b/backend/project/api/events/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/project/api/events/apps.py b/backend/project/api/events/apps.py new file mode 100644 index 0000000..99c73f0 --- /dev/null +++ b/backend/project/api/events/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class EventsConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "api.events" diff --git a/backend/project/api/events/migrations/0001_initial.py b/backend/project/api/events/migrations/0001_initial.py new file mode 100644 index 0000000..ef9d22c --- /dev/null +++ b/backend/project/api/events/migrations/0001_initial.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.11 on 2024-04-02 00:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('title', models.CharField(max_length=255)), + ('users', models.ManyToManyField(blank=True, related_name='events', to='users.user')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/backend/project/api/events/migrations/__init__.py b/backend/project/api/events/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/project/api/events/models.py b/backend/project/api/events/models.py new file mode 100644 index 0000000..ed10a3c --- /dev/null +++ b/backend/project/api/events/models.py @@ -0,0 +1,15 @@ +from django.db import models + +from api.core.models import BaseModel + + +class Event(BaseModel): + title = models.CharField(max_length=255) + users = models.ManyToManyField( + "users.User", + related_name="events", + blank=True, + ) + + def __str__(self): + return self.title diff --git a/backend/project/api/events/serializers.py b/backend/project/api/events/serializers.py new file mode 100644 index 0000000..6d57dd4 --- /dev/null +++ b/backend/project/api/events/serializers.py @@ -0,0 +1,9 @@ +from rest_framework import serializers + +from api.events.models import Event + + +class EventSerializer(serializers.ModelSerializer): + class Meta: + model = Event + fields = "__all__" diff --git a/backend/project/api/events/urls.py b/backend/project/api/events/urls.py new file mode 100644 index 0000000..b2734da --- /dev/null +++ b/backend/project/api/events/urls.py @@ -0,0 +1,9 @@ +from django.urls import path + +from api.events.views import CreateEventView + +app_name = "events" + +urlpatterns = [ + path("create/", CreateEventView.as_view(), name="create"), +] diff --git a/backend/project/api/events/views.py b/backend/project/api/events/views.py new file mode 100644 index 0000000..a6a9941 --- /dev/null +++ b/backend/project/api/events/views.py @@ -0,0 +1,8 @@ +from rest_framework.generics import CreateAPIView + +from api.events.serializers import EventSerializer + + +class CreateEventView(CreateAPIView): + http_method_names = ("post",) + serializer_class = EventSerializer diff --git a/backend/project/api/urls.py b/backend/project/api/urls.py index 5826b60..994cea0 100644 --- a/backend/project/api/urls.py +++ b/backend/project/api/urls.py @@ -1,3 +1,12 @@ from django.urls import include, path -urlpatterns = [] +urlpatterns = [ + path( + "users/", + include("api.users.urls", namespace="users"), + ), + path( + "events/", + include("api.events.urls", namespace="events"), + ) +] diff --git a/backend/project/api/users/__init__.py b/backend/project/api/users/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/project/api/users/apps.py b/backend/project/api/users/apps.py new file mode 100644 index 0000000..079b9a5 --- /dev/null +++ b/backend/project/api/users/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class UsersConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "api.users" diff --git a/backend/project/api/users/migrations/0001_initial.py b/backend/project/api/users/migrations/0001_initial.py new file mode 100644 index 0000000..2e8a491 --- /dev/null +++ b/backend/project/api/users/migrations/0001_initial.py @@ -0,0 +1,30 @@ +# Generated by Django 4.2.11 on 2024-04-02 00:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('first_name', models.CharField(max_length=255)), + ('last_name', models.CharField(max_length=255)), + ('email', models.EmailField(max_length=254)), + ('birth_date', models.DateTimeField()), + ('bio', models.TextField()), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/backend/project/api/users/migrations/__init__.py b/backend/project/api/users/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/project/api/users/models.py b/backend/project/api/users/models.py new file mode 100644 index 0000000..fb02494 --- /dev/null +++ b/backend/project/api/users/models.py @@ -0,0 +1,14 @@ +from django.db import models + +from api.core.models import BaseModel + + +class User(BaseModel): + first_name = models.CharField(max_length=255) + last_name = models.CharField(max_length=255) + email = models.EmailField() + birth_date = models.DateTimeField() + bio = models.TextField() + + def __str__(self): + return f"{self.first_name} {self.last_name}" diff --git a/backend/project/api/users/serializers.py b/backend/project/api/users/serializers.py new file mode 100644 index 0000000..b669fa5 --- /dev/null +++ b/backend/project/api/users/serializers.py @@ -0,0 +1,24 @@ +from rest_framework import serializers + +from api.events.models import Event +from api.users.models import User + + +class UserSerializer(serializers.ModelSerializer): + class Meta: + model = User + fields = "__all__" + + def create(self, validated_data): + try: + event = Event.objects.get( + pk=self.context["view"].kwargs.get("event_id") + ) + except Event.DoesNotExist as e: + msg = "Event does not exist" + raise serializers.ValidationError(msg) from e + + user = User.objects.create(**validated_data) + event.users.add(user) + + return user diff --git a/backend/project/api/users/urls.py b/backend/project/api/users/urls.py new file mode 100644 index 0000000..1c4ab6f --- /dev/null +++ b/backend/project/api/users/urls.py @@ -0,0 +1,17 @@ +from django.urls import path + +from api.users.views import ( + RegisterUsersFromExcelView, + RegisterUserView, +) + +app_name = "users" + +urlpatterns = [ + path("register//", RegisterUserView.as_view(), name="register"), + path( + "upload/excel//", + RegisterUsersFromExcelView.as_view(), + name="excel-upload", + ), +] diff --git a/backend/project/api/users/views.py b/backend/project/api/users/views.py new file mode 100644 index 0000000..a701a21 --- /dev/null +++ b/backend/project/api/users/views.py @@ -0,0 +1,66 @@ +from pathlib import Path + +import pandas as pd +from rest_framework import status +from rest_framework.generics import CreateAPIView +from rest_framework.response import Response +from rest_framework.views import APIView +from rest_framework.viewsets import ReadOnlyModelViewSet + +from api.events.models import Event +from api.users.models import User +from api.users.serializers import UserSerializer + + +class RegisterUserView(CreateAPIView): + http_method_names = ("post",) + serializer_class = UserSerializer + + +class UserViewSet(ReadOnlyModelViewSet): + queryset = User.objects.all() + serializer_class = UserSerializer + + +#! Починить вьюшку, сделать экспорт +class RegisterUsersFromExcelView(APIView): + def post(self, request, event_id): + try: + event = Event.objects.get(pk=event_id) + except Event.DoesNotExist: + return Response( + {"error": "Event does not exist"}, + status=status.HTTP_404_NOT_FOUND, + ) + + excel_file = request.FILES.get("excel_file") + if not excel_file: + return Response( + {"error": "No Excel file provided"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + try: + df = pd.read_excel(excel_file) + + for index, row in df.iterrows(): + # Создаем нового пользователя + user = User.objects.create( + first_name=row["First Name"], + last_name=row["Last Name"], + email=row["Email"], + birth_date=row["Birth Date"], + bio=row["Bio"], + ) + + event.users.add(user) + + return Response( + {"success": "Users registered successfully"}, + status=status.HTTP_201_CREATED, + ) + + except Exception as e: + return Response( + {"error": str(e)}, status=status.HTTP_400_BAD_REQUEST + ) diff --git a/backend/project/config/settings.py b/backend/project/config/settings.py index 6110d21..f5b7c23 100755 --- a/backend/project/config/settings.py +++ b/backend/project/config/settings.py @@ -46,6 +46,9 @@ INSTALLED_APPS = [ "corsheaders", "drf_yasg", # Developed apps + "api", + "api.users", + "api.events", ] MIDDLEWARE = [