diff --git a/app/conf/api.py b/app/conf/api.py index 3df281e..fc2f0c1 100644 --- a/app/conf/api.py +++ b/app/conf/api.py @@ -2,7 +2,16 @@ from django.urls import path, include from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView from marketplace.api.views import ListCreateProductApi, RetireUpdateDestroyProductApi -from users.api.views import ListCreateUserApi +from users.api.views import ( + ListCreateUserApi, + RetireUpdateDeleteUserApi, + ListCreateDepartmentApi, + RetireUpdateDeleteDepartmentApi, + ListCreateStreamApi, + RetireUpdateDeleteStreamApi, + ListCreateCommandApi, + RetireUpdateDeleteCommandApi, +) urlpatterns = [ path( @@ -35,7 +44,47 @@ urlpatterns = [ "users/", include( [ - path("", ListCreateUserApi.as_view(), name="user_list_create"), + path("", ListCreateUserApi.as_view(), name="list_create_user"), + path( + "", + RetireUpdateDeleteUserApi.as_view(), + name="get_update_delete_user", + ), + path( + "department/", + ListCreateDepartmentApi.as_view(), + name="list_create_department", + ), + path( + "department/", + ListCreateDepartmentApi.as_view(), + name="list_create_department", + ), + path( + "department/", + RetireUpdateDeleteDepartmentApi.as_view(), + name="get_update_delete_department", + ), + path( + "stream/", + ListCreateStreamApi.as_view(), + name="list_create_stream", + ), + path( + "stream/", + RetireUpdateDeleteStreamApi.as_view(), + name="get_update_delete_stream", + ), + path( + "command/", + ListCreateCommandApi.as_view(), + name="list_create_command", + ), + path( + "command/", + RetireUpdateDeleteCommandApi.as_view(), + name="get_update_delete_command", + ), ] ), ), diff --git a/app/marketplace/api/views.py b/app/marketplace/api/views.py index 9f9c2ae..8787a6e 100644 --- a/app/marketplace/api/views.py +++ b/app/marketplace/api/views.py @@ -22,8 +22,8 @@ class RetireUpdateDestroyProductApi(generics.RetrieveUpdateDestroyAPIView): queryset = Product.objects.all() def get_object(self): - block = get_object_or_404( + product = get_object_or_404( Product, slug=self.request.parser_context["kwargs"]["slug"], ) - return block + return product diff --git a/app/users/api/serializers.py b/app/users/api/serializers.py index 1da84b7..d534f55 100644 --- a/app/users/api/serializers.py +++ b/app/users/api/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers -from users.models import User +from users.models import User, Department, Stream, Command class UserSerializer(serializers.ModelSerializer): @@ -15,10 +15,13 @@ class UserSerializer(serializers.ModelSerializer): "salary", "respect", "wallet_public_key", + "command", + "department", ] extra_kwargs = { "password": {"write_only": True}, "wallet_public_key": {"read_only": True}, + "department": {"read_only": True}, } def create(self, validated_data): @@ -26,3 +29,41 @@ class UserSerializer(serializers.ModelSerializer): **validated_data, username=validated_data["telegram"] ) return user + + +class CommandSerializer(serializers.ModelSerializer): + workers = UserSerializer(many=True) + + class Meta: + model = Command + fields = ["id", "name", "stream", "workers"] + extra_kwargs = { + "id": {"read_only": True}, + "stream": {"write_only": True}, + "workers": {"read_only": True}, + } + + +class StreamSerializer(serializers.ModelSerializer): + commands = CommandSerializer(many=True) + + class Meta: + model = Stream + fields = ["id", "name", "department", "commands"] + extra_kwargs = { + "id": {"read_only": True}, + "department": {"write_only": True}, + "commands": {"read_only": True}, + } + + +class DepartmentSerializer(serializers.ModelSerializer): + streams = StreamSerializer(many=True) + + class Meta: + model = Department + fields = ["id", "name", "streams"] + extra_kwargs = { + "id": {"read_only": True}, + "streams": {"read_only": True}, + } diff --git a/app/users/api/views.py b/app/users/api/views.py index b00e165..817a1d1 100644 --- a/app/users/api/views.py +++ b/app/users/api/views.py @@ -1,12 +1,64 @@ from rest_framework import generics +from rest_framework.generics import get_object_or_404 from rest_framework.permissions import IsAuthenticated from common.permissions import IsAdmin -from users.api.serializers import UserSerializer -from users.models import User +from users.api.serializers import ( + UserSerializer, + DepartmentSerializer, + StreamSerializer, + CommandSerializer, +) +from users.models import User, Department, Stream, Command class ListCreateUserApi(generics.ListCreateAPIView): serializer_class = UserSerializer permission_classes = [IsAuthenticated, IsAdmin] queryset = User.objects.all() + + +class RetireUpdateDeleteUserApi(generics.RetrieveUpdateDestroyAPIView): + def get_object(self): + user = get_object_or_404( + User, + username=self.request.parser_context["kwargs"]["username"], + ) + return user + + serializer_class = UserSerializer + permission_classes = [IsAuthenticated, IsAdmin] + queryset = User.objects.all() + + +class ListCreateDepartmentApi(generics.ListCreateAPIView): + serializer_class = DepartmentSerializer + permission_classes = [IsAuthenticated, IsAdmin] + queryset = Department.objects.all() + + +class RetireUpdateDeleteDepartmentApi(generics.RetrieveUpdateDestroyAPIView): + lookup_field = "pk" + serializer_class = DepartmentSerializer + permission_classes = [IsAuthenticated, IsAdmin] + queryset = Department.objects.all() + + +class ListCreateStreamApi(ListCreateDepartmentApi): + serializer_class = StreamSerializer + queryset = Stream.objects.all() + + +class RetireUpdateDeleteStreamApi(RetireUpdateDeleteDepartmentApi): + serializer_class = StreamSerializer + queryset = Stream.objects.all() + + +class ListCreateCommandApi(ListCreateDepartmentApi): + serializer_class = CommandSerializer + queryset = Command.objects.all() + + +class RetireUpdateDeleteCommandApi(RetireUpdateDeleteDepartmentApi): + serializer_class = CommandSerializer + queryset = Command.objects.all() diff --git a/app/users/models.py b/app/users/models.py index a8ddfc3..e904b01 100644 --- a/app/users/models.py +++ b/app/users/models.py @@ -1,16 +1,6 @@ from django.contrib.auth.models import AbstractUser from django.core.validators import MinValueValidator from django.db import models -from faker import Faker - - -class Clan(models.Model): - name = models.CharField(max_length=100, null=True) - - def save(self, *args, **kwargs): - name = Faker().name() - self.name = name + "'s clan" - super(Clan, self).save(*args, **kwargs) class User(AbstractUser): @@ -26,17 +16,19 @@ class User(AbstractUser): # image_cropped = models.ImageField(upload_to="cropped/", blank=True) about = models.TextField(blank=True) - name = models.CharField(max_length=120, null=True) + name = models.CharField(max_length=120) type = models.CharField( max_length=6, choices=WorkerType.choices, default=WorkerType.WORKER ) - salary = models.IntegerField(default=0) - clan = models.ForeignKey(Clan, on_delete=models.CASCADE, null=True) + command = models.ForeignKey( + "users.Command", related_name="workers", on_delete=models.CASCADE + ) + salary = models.IntegerField(default=0, validators=[MinValueValidator(0)]) respect = models.IntegerField(default=0, validators=[MinValueValidator(0)]) - wallet_private_key = models.CharField(max_length=96, unique=True, null=True) - wallet_public_key = models.CharField(max_length=96, unique=True, null=True) - telegram = models.CharField(max_length=100, unique=True, null=True) + wallet_private_key = models.CharField(max_length=96, unique=True) + wallet_public_key = models.CharField(max_length=96, unique=True) + telegram = models.CharField(max_length=100, unique=True) def __str__(self): return self.username @@ -49,5 +41,36 @@ class User(AbstractUser): def is_admin(self): return self.type == self.WorkerType.ADMIN + @property + def department(self): + return self.command.stream.department.name + class Meta: - ordering = ["-id"] \ No newline at end of file + ordering = ["-id"] + + +class Department(models.Model): + name = models.CharField(max_length=100) + + def __str__(self): + return self.name + + +class Stream(models.Model): + name = models.CharField(max_length=100) + department = models.ForeignKey( + Department, related_name="streams", on_delete=models.CASCADE + ) + + def __str__(self): + return self.name + + +class Command(models.Model): + name = models.CharField(max_length=100) + stream = models.ForeignKey( + Stream, related_name="commands", on_delete=models.CASCADE + ) + + def __str__(self): + return self.name