Вычислить поле 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").

Я не уверен, но думаю, что вам следует удалить "число" из списка полей в сериализаторе, поскольку вы его вычисляете.

Вернуться на верх