Django Rest Framework, запрос POST, обновление если существует, создание если не существует из массовых данных POST запроса

Я создаю API для информационных данных о пользователях. Я хочу сделать так, чтобы при POST запросе, выполнялась функция "создать", "обновить"

если из POST запроса пользователь существует:

update (full_name, function, department, logon, system, lic_type )

если из POST запроса пользователь не существует:

create (user, full_name, function, department, logon, system, lic_type )

models.py

from django.db import models

class Users(models.Model):

user = models.CharField(max_length=50,blank=True, null=True)
full_name = models.CharField(max_length=200, blank=True, null=True)
function = models.CharField(max_length=300,blank=True, null=True)
department = models.CharField(max_length=300,blank=True, null=True)
logon = models.DateTimeField(blank=True, null=True)
system = models.CharField(max_length=300,blank=True, null=True)
lic_type = models.CharField(max_length=300,blank=True, null=True)

serizlizers.py

from rest_framework import serializers
from .models import Users

class UsersSerializer(serializers.ModelSerializer):
    logon = serializers.DateTimeField(input_formats=settings.DATE_INPUT_FORMATS)
    
    class Meta:
        model = Users
        # fields = '__all__'
        fields = ['user', 'full_name', 'function', 'department', 'logon', 'system', 'lic_type']

views.py

from django.http.response import JsonResponse
from rest_framework.parsers import JSONParser
from rest_framework import status

from .models import Users
from .serializers import UsersSerializer
from rest_framework.decorators import api_view, authentication_classes
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
from rest_framework.authentication import BasicAuthentication


@csrf_exempt
@api_view(['GET', 'POST'])
@authentication_classes([BasicAuthentication])
def users_list(request):
    if request.method == 'GET':
        users = Users.objects.all()

        user = request.GET.get('user', None)
        if user is not None:
            users = users.filter(user__icontains=user)

        users_serializer = UsersSerializer(users, many=True)
        return JsonResponse(users_serializer.data, safe=False)

    elif request.method == 'POST':
        users_data = JSONParser().parse(request)
        users_serializer = UsersSerializer(data=users_data, many=True)
        if users_serializer.is_valid():
            users_serializer.save()
            return Response(users_serializer.data, status=status.HTTP_201_CREATED)
        return Response(users_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('users/', views.users_list),
]

Я мог бы сделать так, при POST запросе удалить все из базы данных и создать данные из POST запроса

elif request.method == 'POST':
    users = Users.objects.all()
    users.delete()
    users_data = JSONParser().parse(request)
    users_serializer = UsersSerializer(data=users_data, many=True)
    if users_serializer.is_valid():
        users_serializer.save()
        return Response(users_serializer.data, status=status.HTTP_201_CREATED)
    return Response(users_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

но вместо этого я хочу сделать update_or_create(). Я пробовал так, но это только создает пустую строку в базе данных

    user_name = request.POST.get('user')
    user, created = Users.objects.update_or_create(user = user_name)
    user.full_name = request.POST.get('full_name')
    user.function = request.POST.get('function')
    user.department = request.POST.get('department')
    user.logon = request.POST.get('logon')
    user.system = request.POST.get('system')
    user.lic_type = request.POST.get('lic_type')
    user.save()
    return Response(user, status=status.HTTP_201_CREATED)

спасибо за любую помощь

Лучший способ - когда есть POST, сначала получить элемент из базы данных (используя утилиту django get_object_or_404) и попросить restframework обновить все поля, которые вы установили как нечитаемые в сериализаторе

Пример:

# on top import
from django.shortcuts import get_object_or_404

....
elif request.method == 'POST':
    # add here the query you determine is user already exists, usually a unique ID or UUID
    user_object = get_object_or_404(Users, id=request.data.get('id'))

    users_data = JSONParser().parse(request)
    users_serializer = UsersSerializer(user_object, data=users_data, many=True)
    if users_serializer.is_valid():
        users_serializer.save()
        return Response(users_serializer.data, status=status.HTTP_201_CREATED)
    return Response(users_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Что-то вроде этого должно работать. Вам все еще нужно немного подправить get object

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