В последнее время я работаю над своим первым API, основанным на фреймворке django, и у меня возникла проблема. Вот мой код:
models.py
from django.db import models
from multiselectfield import MultiSelectField
COUNTRY_LIST = [('PL', 'Poland'), ('DE', 'Germany'), ('FI', 'Finland'), ('DK', 'Denmark'), ('SE', 'Sweden')]
CLIENTS_LIST = [('CP1', 'Company1'), ('CP2', 'Company2'), ('CP3', 'Company3')]
TRANSPORTS_LIST = [('V', 'Vehicle'), ('P', 'Plane'), ('T', 'Train'), ('S', 'Ship')]
STATUS_LIST = [('NW', 'New'), ('WC', 'Wait for confirmation'), ('AC', 'Accepted'), ('CL', 'Closed')]
class Trip(models.Model):
startDate = models.DateField()
endDate = models.DateField()
place = models.CharField(max_length=100)
country = models.CharField(choices=COUNTRY_LIST, max_length=2)
client = models.CharField(choices=CLIENTS_LIST, max_length=3, default='NA')
transport = MultiSelectField(choices=TRANSPORTS_LIST)
acommodations = models.BooleanField()
tripStatus = models.CharField(
choices=STATUS_LIST, max_length=2, default='NW')
remarks = models.TextField(blank=True)
employeeId = models.IntegerField()
tripIdentifier = models.CharField(max_length=10)
serializers.py
from rest_framework import serializers
from trips.models import Trip, COUNTRY_LIST, CLIENTS_LIST, TRANSPORTS_LIST, STATUS_LIST
# Trip Serializer
class TripSerializer(serializers.ModelSerializer):
country = serializers.CharField(source='get_country_display')
client = serializers.CharField(source='get_client_display')
transport = serializers.CharField(source='get_transport_display')
tripStatus = serializers.CharField(source='get_tripStatus_display')
class Meta:
model = Trip
fields = '__all__'
api_views.py
from rest_framework.exceptions import ValidationError
from rest_framework.generics import ListAPIView, CreateAPIView, RetrieveUpdateDestroyAPIView
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter
from trips.serializers import TripSerializer
from trips.models import Trip
import re
class TripList(ListAPIView):
queryset = Trip.objects.all()
serializer_class = TripSerializer
filter_backends = (DjangoFilterBackend, SearchFilter)
search_fields = ("tripIdentifier", "id")
filter_fields = ('id', 'tripStatus', 'employeeId')
class TripCreate(CreateAPIView):
serializer_class = TripSerializer
def create(self, request, *args, **kwargs):
return super().create(request, *args, **kwargs)
class TripRetrieveUpdateDelete(RetrieveUpdateDestroyAPIView):
queryset = Trip.objects.all()
lookup_field = 'id'
serializer_class = TripSerializer
def delete(self, request, *args, **kwargs):
trip_id = request.data.get('id')
response = super().delete(request, *args, **kwargs)
if response.status_code == 204:
from django.core.cache import cache
cache.delete('trip_data_{}'.format(trip_id))
return response
def update(self, request, *args, **kwargs):
response = super().update(request, *args, **kwargs)
if response.status_code == 200:
from django.core.cache import cache
trip = response.data
cache.set('trip_data_{}'.format(trip['id']), {
'startDate': trip['startDate'],
'endDate': trip['endDate'],
'place': trip['place'],
'employeeId': trip['employeeId'],
})
return response
urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.conf.urls import url
from django.contrib import admin
from django.urls import path, include
import employee.views
import employee.api_views
import trips.views
import trips.api_views
urlpatterns = [
path('admin/', admin.site.urls),
path('employee', employee.api_views.EmployeeList.as_view()),
path('employee/new', employee.api_views.EmployeeCreate.as_view()),
path('employee/<int:id>',
employee.api_views.EmployeeRetrieveUpdateDelete.as_view()),
path('trip', trips.api_views.TripList.as_view()),
path('trip/new', trips.api_views.TripCreate.as_view()),
path('trip/<int:id>', trips.api_views.TripRetrieveUpdateDelete.as_view())
]
Вот описание проблемы: запросы Get, Put и Delete работают нормально. Но когда я вызываю POST-запрос и пытаюсь добавить новую Trip, я получаю сообщение об ошибке:
TypeError at /trip/new
Got a `TypeError` when calling `Trip.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `Trip.objects.create()`. You may need to make the field read-only, or override the TripSerializer.create() method to handle this correctly.
Original exception was:
Traceback (most recent call last):
File "C:\Users\User\.virtualenvs\RadiolineExtranet-iRF8Rd_0\lib\site-packages\rest_framework\serializers.py", line 932, in create
instance = ModelClass._default_manager.create(**validated_data)
File "C:\Users\User\.virtualenvs\RadiolineExtranet-iRF8Rd_0\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\User\.virtualenvs\RadiolineExtranet-iRF8Rd_0\lib\site-packages\django\db\models\query.py", line 420, in create
obj = self.model(**kwargs)
File "C:\Users\User\.virtualenvs\RadiolineExtranet-iRF8Rd_0\lib\site-packages\django\db\models\base.py", line 501, in __init__
raise TypeError("%s() got an unexpected keyword argument '%s'" % (cls.__name__, kwarg))
TypeError: Trip() got an unexpected keyword argument 'get_country_display'
Не могли бы вы немного помочь мне понять, что не так с моим кодом?