From 902b0796a4b6167cd41f9e50a5a093656779043a Mon Sep 17 00:00:00 2001 From: behruz-dev Date: Sat, 22 Nov 2025 16:56:56 +0500 Subject: [PATCH] Place model va apilar qoshildi --- core/apps/shared/admin/__init__.py | 3 +- core/apps/shared/admin/place.py | 10 ++++ core/apps/shared/serializers/place.py | 56 ++++++++++++++++++++++ core/apps/shared/urls.py | 11 +++++ core/apps/shared/views/district.py | 2 +- core/apps/shared/views/place.py | 69 +++++++++++++++++++++++++++ 6 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 core/apps/shared/admin/place.py create mode 100644 core/apps/shared/serializers/place.py create mode 100644 core/apps/shared/views/place.py diff --git a/core/apps/shared/admin/__init__.py b/core/apps/shared/admin/__init__.py index 626891d..2ff5e06 100644 --- a/core/apps/shared/admin/__init__.py +++ b/core/apps/shared/admin/__init__.py @@ -1,2 +1,3 @@ from .region import * -from .district import * \ No newline at end of file +from .district import * +from .place import * \ No newline at end of file diff --git a/core/apps/shared/admin/place.py b/core/apps/shared/admin/place.py new file mode 100644 index 0000000..dd101cf --- /dev/null +++ b/core/apps/shared/admin/place.py @@ -0,0 +1,10 @@ +from django.contrib import admin + +# shared +from core.apps.shared.models import Place + + +@admin.register(Place) +class PlaceAdmin(admin.ModelAdmin): + list_display = ['name', 'user', 'district'] + search_fields = ['name'] \ No newline at end of file diff --git a/core/apps/shared/serializers/place.py b/core/apps/shared/serializers/place.py new file mode 100644 index 0000000..7a9615a --- /dev/null +++ b/core/apps/shared/serializers/place.py @@ -0,0 +1,56 @@ +# django +from django.db import transaction + +# rest framework +from rest_framework import serializers + +# shared +from core.apps.shared.models import Place, District + + +class PlaceSerializer(serializers.ModelSerializer): + district = serializers.SerializerMethodField() + + class Meta: + model = Place + fields = [ + 'id', 'name', 'latitude', 'longitude', 'extra_location', 'district', 'created_at' + ] + + def get_district(self, obj): + return { + "id": obj.district.id, + "name": obj.district.name, + } + + +class PlaceCreateSerializer(serializers.Serializer): + name = serializers.CharField() + latitude = serializers.FloatField() + longitude = serializers.FloatField() + extra_location = serializers.JSONField() + district_id = serializers.IntegerField() + + def validate_name(self, value): + if not Place.objects.filter(name=value).exists(): + raise serializers.ValidationError({"name": "Place bu name bilan mavjud"}) + return value + + def validate(self, data): + district = District.objects.filter(id=data['district_id']).first() + if not district: + raise serializers.ValidationError({"district_id": "District not found"}) + data['district'] = district + return data + + def create(self, validated_data): + with transaction.atomic(): + return Place.objects.create( + name=validated_data.get('name'), + latitude=validated_data.get('latitude'), + longitude=validated_data.get('longitude'), + extra_location=validated_data.get('extra_location'), + district=validated_data.get('district'), + user=self.context.get('user'), + ) + diff --git a/core/apps/shared/urls.py b/core/apps/shared/urls.py index c14916e..4f9b8e5 100644 --- a/core/apps/shared/urls.py +++ b/core/apps/shared/urls.py @@ -4,18 +4,29 @@ from django.urls import path, include from core.apps.shared.views import region as region_view # shared district view from core.apps.shared.views import district as dis_view +# shared place view +from core.apps.shared.views import place as pl_view urlpatterns = [ + # region path('region/', include( [ path('list/', region_view.RegionListApiView.as_view(), name='region-list-api'), ], )), + # district path('disctrict/', include( [ path('list/', dis_view.DistrictListApiView.as_view(), name='district-list-api'), path('create/', dis_view.DistrictCreateApiView.as_view(), name='district-create-api'), ], )), + # place + path('place/', include( + [ + path('list/', pl_view.PlaceListApiView.as_view(), name='place-list-api'), + path('create/', pl_view.PlaceCreateApiView.as_view(), name='place-create-api'), + ] + )), ] \ No newline at end of file diff --git a/core/apps/shared/views/district.py b/core/apps/shared/views/district.py index 9d5bf68..280c82f 100644 --- a/core/apps/shared/views/district.py +++ b/core/apps/shared/views/district.py @@ -48,7 +48,7 @@ class DistrictCreateApiView(generics.CreateAPIView, ResponseMixin): def post(self, request): try: serializer = self.serializer_class(data=request.data) - if serializer.is_valid(raise_exception=True): + if serializer.is_valid(): name = serializer.validated_data.get('name') obj = District.objects.create(name=name, user=request.user) return self.success_response( diff --git a/core/apps/shared/views/place.py b/core/apps/shared/views/place.py new file mode 100644 index 0000000..bf5564f --- /dev/null +++ b/core/apps/shared/views/place.py @@ -0,0 +1,69 @@ +# rest framework +from rest_framework import generics, permissions + +# drf yasg +from drf_yasg.utils import swagger_auto_schema + +# shared +from core.apps.shared.models import Place +from core.apps.shared.serializers import base as base_serializer +from core.apps.shared.serializers.place import PlaceSerializer, PlaceCreateSerializer +from core.apps.shared.utils.response_mixin import ResponseMixin + +# accounts +from core.apps.accounts.models import User + + +class PlaceListApiView(generics.GenericAPIView, ResponseMixin): + serializer_class = PlaceSerializer + queryset = Place.objects.all() + permission_classes = [permissions.IsAuthenticated] + + @swagger_auto_schema( + responses={ + 200: base_serializer.SuccessResponseSerializer(), + 400: base_serializer.BaseResponseSerializer(), + 500: base_serializer.BaseResponseSerializer(), + }, + ) + def get(self, request): + try: + search = request.query_params.get('search') + + query = self.queryset.filter(user=request.user) + if search: + query = query.filter(name__istartswith=search) + + page = self.paginate_queryset(query) + if page is not None: + serializer = self.serializer_class(page, many=True) + return self.success_response(data=self.paginate_queryset(serializer.data), message='malumotlar fetch qilindi') + + serializer = self.serializer_class(query, many=True) + return self.success_response(data=serializer.data, message='malumotlar fetch qilindi') + + except Exception as e: + return self.error_response(data=str(e), message='xatolik') + + +class PlaceCreateApiView(generics.GenericAPIView, ResponseMixin): + serializer_class = PlaceCreateSerializer + queryset = Place.objects.all() + permission_classes = [permissions.IsAuthenticated] + + @swagger_auto_schema( + responses={ + 201: base_serializer.SuccessResponseSerializer(), + 400: base_serializer.BaseResponseSerializer(), + 500: base_serializer.BaseResponseSerializer() + } + ) + def post(self, request): + try: + serializer = self.serializer_class(data=request.data, context={'user': request.user}) + if serializer.is_valid(): + instance = serializer.save() + return self.success_response(data=PlaceSerializer(instance).data, message='malumot qoshildi') + return self.failure_response(data=serializer.errors, message='malumot qoshilmadi') + except Exception as e: + return self.error_response(data=str(e), message='xatolik') \ No newline at end of file