Вычислить поле django и сохранить его в базе данных
Я только начинаю работать с Django и веб-разработкой, поэтому прошу быть со мной вежливым. Я пытаюсь создать приложение, которое генерирует новый номер для отчетов, созданных нашими инспекторами (наша компания - инспекционная компания). каждый инспектор выбирает тип отчета, дату проверки и клиента, а приложение сохраняет данные и создает номер отчета. номер отчета создается в зависимости от типа отчета и даты. например, если у меня есть 3 отчета типа "визуальный осмотр", сделанных в 2022 году, новый отчет "визуальный осмотр" будет иметь номер 4/2022.
вот код, который я использовал, чтобы попытаться сделать это, но, к сожалению, он не работает:
Views.py
from modulefinder import ReplacePackage
from django.shortcuts import render
from report.models import Report
from django.http import HttpResponse
from django.db.models.aggregates import Count
from django.db import transaction
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .serializers import ReportSerializer
@api_view(['GET','POST'])
def Report_add_view(request):
if request.method =='GET':
queryset = Report.objects.select_related('type').all()
serializer = ReportSerializer(queryset,many=True)
return Response(serializer.data,status=status.HTTP_200_OK)
elif request.method =='POST':
serializer = ReportSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data,status=status.HTTP_201_CREATED)
# Create your views here.
models.py
from django.db import models
# Create your models here.
class Client(models.Model):
name = models.CharField(max_length = 255)
code = models.PositiveIntegerField()
class ReportType(models.Model):
report_type = models.CharField(max_length = 255)
report_code = models.CharField(max_length = 255)
report_rev = models.CharField(max_length = 20)
def __str__(self):
return self.report_type
class Inspector(models.Model):
first_name = models.CharField(max_length = 255)
last_name = models.CharField(max_length = 255)
full_name = models.CharField(max_length = 255)
class Report (models.Model):
number = models.CharField(max_length=100)
type = models.CharField(max_length = 255)
inspection_date = models.DateField()
date_created = models.DateTimeField(auto_now_add=True)
inspector = models.ForeignKey(Inspector,on_delete=models.PROTECT)
client = models.ForeignKey(Client,on_delete=models.PROTECT)
type = models.ForeignKey(ReportType,on_delete=models.PROTECT)
reportlink = models.TextField()
serializers.py
from rest_framework import serializers
from .models import *
from django.db.models.aggregates import Count
from django.db.models import F
class ReportSerializer(serializers.ModelSerializer):
class Meta:
fields = ['number','type','inspection_date','inspector','client','reportlink','date_created']
model = Report
number = serializers.SerializerMethodField(method_name='report_number')
def report_number(self, report:Report):
print(report.type_id)
num1 = Report.objects.filter(type_id = report.type_id).all().aggregate(num=Count('id'))['num']+1
year = str(report.inspection_date)[:4]
print(year)
print(num1)
return str(num1) + "/"+ year
class InspectorSerializer(serializers.ModelSerializer):
class Meta:
fields = ['first_name','last_name','full_name']
model = Inspector
class ReportTypeSerializer(serializers.ModelSerializer):
class Meta:
fields = ['report_type','report_code','report_rev']
model = Report
Как указано в документе DRF: https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield. SerializerMethodField является полем только для чтения.
Чтобы достичь того, что вы пытаетесь сделать, я бы переопределил метод "create" сериализатора. В качестве параметра он принимает dict validated_data (генерируется благодаря вызову is_valid, который вы делаете).
.
В этом методе вы должны иметь возможность установить validated_data["number"] в желаемое значение (верните измененный dict в конце метода "create").
Я не уверен, но думаю, что вам следует удалить "число" из списка полей в сериализаторе, поскольку вы его вычисляете.