add: order model, order create api, order create serializer, order item model

This commit is contained in:
behruz-dev
2025-08-29 16:34:15 +05:00
parent 6aa82a74e7
commit 4f45b97aaa
11 changed files with 192 additions and 3 deletions

View File

@@ -4,7 +4,7 @@ CORS_ALLOWED_ORIGINS = [
]
CSRF_TRUSTED_ORIGINS = [
'http://localhost:8001',
'http://127.0.0.1:8001',
'http://localhost:8080',
'http://127.0.0.1:8080',
'https://horeca.felixits.uz',
]

View File

@@ -0,0 +1 @@
from .order import *

View File

@@ -0,0 +1,14 @@
from django.contrib import admin
from core.apps.orders.models.order import Order, OrderItem
class OrderItemInline(admin.TabularInline):
model = OrderItem
extra = 0
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
list_display = ['id', 'user', 'total_price']
inlines = [OrderItemInline]

View File

@@ -4,3 +4,6 @@ from django.apps import AppConfig
class OrdersConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'core.apps.orders'
def ready(self):
from . import admin

View File

@@ -0,0 +1,45 @@
# Generated by Django 5.2 on 2025-08-29 16:13
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Order',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('total_price', models.PositiveBigIntegerField(default=0)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Buyurtma',
'verbose_name_plural': 'Buyurtmalar',
},
),
migrations.CreateModel(
name='OrderItem',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('quantity', models.PositiveIntegerField()),
('price', models.PositiveBigIntegerField()),
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='orders.order')),
],
options={
'verbose_name': 'Buyurtma elementi',
'verbose_name_plural': 'Buyurtma elementlari',
},
),
]

View File

@@ -0,0 +1,20 @@
# Generated by Django 5.2 on 2025-08-29 16:17
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('orders', '0001_initial'),
('products', '0002_category_name_ru_category_name_uz_and_more'),
]
operations = [
migrations.AddField(
model_name='orderitem',
name='product',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='items', to='products.product'),
),
]

View File

@@ -0,0 +1 @@
from .order import *

View File

@@ -0,0 +1,31 @@
from django.db import models
from core.apps.shared.models import BaseModel
from core.apps.accounts.models import User
from core.apps.products.models import Product
class Order(BaseModel):
total_price = models.PositiveBigIntegerField(default=0)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='orders')
def __str__(self):
return f'{self.user} order'
class Meta:
verbose_name = 'Buyurtma'
verbose_name_plural = 'Buyurtmalar'
class OrderItem(BaseModel):
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='items')
quantity = models.PositiveIntegerField()
price = models.PositiveBigIntegerField()
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='items', null=True)
def __str__(self):
return f'{self.quantity} - {self.price} to {self.order}'
class Meta:
verbose_name = 'Buyurtma elementi'
verbose_name_plural = 'Buyurtma elementlari'

View File

@@ -0,0 +1,45 @@
from django.db import transaction
from rest_framework import serializers
from core.apps.orders.models import Order, OrderItem
from core.apps.products.models import Product
class OrderItemCreateSerializer(serializers.Serializer):
product_id = serializers.UUIDField()
quantity = serializers.IntegerField()
def validate(self, data):
product = Product.objects.filter(id=data['product_id']).first()
if not product:
raise serializers.ValidationError("Product not found")
data['product'] = product
data['price'] = product.price * data['quantity']
return data
class OrderCreateSerializer(serializers.Serializer):
items = OrderItemCreateSerializer(many=True)
def create(self, validated_data):
with transaction.atomic():
order_items = validated_data.pop('items')
order = Order.objects.create(
user=self.context.get('user'),
)
items = []
total_price = 0
for item in order_items:
items.append(OrderItem(
product=item.get('product'),
price=item.get('price'),
quantity=item.get('quantity'),
order=order,
))
total_price += item.get('price')
OrderItem.objects.bulk_create(items)
order.total_price = total_price
order.save()
return order

View File

@@ -1,6 +1,7 @@
from django.urls import path, include
from core.apps.orders.views import order as order_views
urlpatterns = [
path('order/create/', order_views.OrderCreateApiView.as_view()),
]

View File

@@ -0,0 +1,28 @@
from rest_framework import generics, permissions
from rest_framework.response import Response
from core.apps.orders.models import Order, OrderItem
from core.apps.orders.serializers import order as serializers
class OrderCreateApiView(generics.GenericAPIView):
serializer_class = serializers.OrderCreateSerializer
queryset = Order.objects.all()
permission_classes = [permissions.IsAuthenticated]
def post(self, request):
serializer = self.serializer_class(data=request.data, context={'user': request.user})
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(
{'success': True, 'message': 'Firdavs aka order create qilindi, tekshirib koring'},
status=200
)
return Response(
{
'success': False,
"message": "Firdavs aka order create qilishda xatolik chiqdi, errorni oqib koring",
'error': serializer.errors,
},
status=400
)