file attechment for ticket

This commit is contained in:
Parsa Nazer
2025-02-23 14:34:42 +03:30
parent f9daff02d5
commit 362777bf7c
5 changed files with 101 additions and 5 deletions
@@ -0,0 +1,33 @@
# Generated by Django 5.1.2 on 2025-02-22 22:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ticket', '0012_alter_ticket_status'),
]
operations = [
migrations.CreateModel(
name='Attachment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to='attachments')),
('created_at', models.DateTimeField(auto_now_add=True)),
('size', models.PositiveIntegerField(blank=True, null=True)),
('name', models.CharField(blank=True, max_length=400, null=True)),
],
),
migrations.AddField(
model_name='message',
name='attachments',
field=models.ManyToManyField(blank=True, related_name='messages', to='ticket.attachment'),
),
migrations.AddField(
model_name='ticket',
name='attachments',
field=models.ManyToManyField(blank=True, related_name='tickets', to='ticket.attachment'),
),
]
+18
View File
@@ -3,6 +3,22 @@ from account.models import User
from order.models import OrderModel
from django_jalali.db import models as jmodels
class Attachment(models.Model):
file = models.FileField(upload_to='attachments')
created_at = models.DateTimeField(auto_now_add=True)
size = models.PositiveIntegerField(null=True, blank=True)
name = models.CharField(max_length=400, null=True, blank=True)
def __str__(self):
return self.file.name
def save(self, *args, **kwargs):
if self.file:
self.size = self.file.size
self.name = self.file.name
super(Attachment, self).save(*args, **kwargs)
class Ticket(models.Model):
objects = jmodels.jManager()
STATUS_CHOICES = [
@@ -28,6 +44,7 @@ class Ticket(models.Model):
created_at = jmodels.jDateTimeField(auto_now_add=True, verbose_name='ساخته شده در')
updated_at = jmodels.jDateTimeField(auto_now=True, verbose_name='اپدیت شده در')
order = models.ForeignKey(OrderModel ,blank=True, null=True, on_delete=models.SET_NULL)
attachments = models.ManyToManyField(Attachment, related_name='tickets', blank=True)
def __str__(self):
return self.subject
@@ -44,6 +61,7 @@ class Message(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='ارسال کننده')
content = models.TextField(verbose_name='محتوای پیام')
created_at = jmodels.jDateTimeField(auto_now_add=True, verbose_name='ساخته شده در')
attachments = models.ManyToManyField(Attachment, related_name='messages', blank=True)
def __str__(self):
return f"Message by {self.sender.full_name} on {self.ticket.subject}"
+20 -1
View File
@@ -1,7 +1,10 @@
from rest_framework import serializers
from .models import Ticket, Message
from .models import Ticket, Message, Attachment
from django.utils.timezone import localtime
from account.serializers import ProfileSerializer
class MessageSerializer(serializers.ModelSerializer):
class Meta:
model = Message
@@ -21,3 +24,19 @@ class TicketListSerializer(serializers.ModelSerializer):
model = Ticket
exclude = ('customer', 'admin', 'order', 'content')
read_only_fields = ('status',)
class AttachmentSerializer(serializers.ModelSerializer):
file = serializers.FileField(write_only=True)
link = serializers.SerializerMethodField()
class Meta:
model = Attachment
fields = ['id', 'name', 'file','link' , 'created_at', 'size']
read_only_fields = ('size', 'name', )
def get_link(self, obj):
request = self.context.get('request')
if request is not None:
return request.build_absolute_uri(obj.file.url)
return obj.file.url
+4 -2
View File
@@ -4,12 +4,14 @@ from .views import (
TicketListView,
TicketDetailView,
MessageCreateView,
UpdateTicketStatusView
UpdateTicketStatusView,
AttachmentUploadView
)
urlpatterns = [
path('create', TicketCreateView.as_view(), name='ticket-create'),
path('', TicketListView.as_view(), name='ticket-list'),
path('<int:pk>', TicketDetailView.as_view(), name='ticket-detail'),
path('message/<int:pk>', MessageCreateView.as_view(), name='message-create'),
path('message/create', MessageCreateView.as_view(), name='message-create'),
path('attachment/create', AttachmentUploadView.as_view(), name='attachment-upload'),
]
+25 -1
View File
@@ -2,9 +2,33 @@ from rest_framework import generics, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Ticket, Message
from .serializers import TicketListSerializer, MessageSerializer, TicketSerializer
from .serializers import TicketListSerializer, MessageSerializer, TicketSerializer, AttachmentSerializer
from utils.pagination import StructurePagination
from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiTypes
from rest_framework.permissions import IsAuthenticated
from rest_framework.parsers import MultiPartParser, FormParser
from drf_spectacular.utils import extend_schema, OpenApiParameter, OpenApiExample, OpenApiTypes, OpenApiResponse
from rest_framework import status
class AttachmentUploadView(APIView):
permission_classes = [IsAuthenticated]
parser_classes = [MultiPartParser, FormParser]
@extend_schema(
request=AttachmentSerializer,
responses={201: AttachmentSerializer},
description="upload an attachment (file).",
)
def post(self, request, *args, **kwargs):
serializer = AttachmentSerializer(data=request.data, context={'request': request})
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class TicketCreateView(generics.CreateAPIView):
queryset = Ticket.objects.all()