django REST 프레임워크에서 request.data를 수정하는 방법
저는 장고 REST 프레임워크를 사용하고 있습니다.
request.data = '{"id": "10", "user": "tom"}'
는 '하다'와 같은 싶어요."age": "30" 같은 하기 전에
request.data = new_data
response = super().post(request, *args, **kwargs)
두 가지 문제가 있습니다.
- request.data가 dict가 아닌 문자열로 제공되는 이유
- request.data 업데이트 방법
가 API인 APIView그런 다음 업데이트 기능을 사용하여 클라이언트 측에서 전송된 데이터를 잃지 않고 요청 데이터 개체를 확장해야 합니다.
request.data.update({"id": "10", "user": "tom"})
request.data는 문자열이 아닌 불변이어야 합니다.수정이 필요한 경우:
if isinstance(request.data, QueryDict): # optional
request.data._mutable = True
request.data['age'] = "30"
인스턴스가 「」의 할 수 는, 「」입니다.QueryDictdict.
좋은 친구가 방금 내가 위에서 설명한 것보다 훨씬 간단한 방법으로 나를 학교에 데려갔다.
class CreateSomething(CreateAPIView):
model = Something
queryset = Something.objects.all()
serializer_class = SomethingSerializer
perform_create(self,serializer):
def perform_create(self,serializer):
ip = self.get_ip()
## magic here: add kwargs for extra fields to write to db
serializer.save(ip_addr=ip)
def get_ip(self):
x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR',None)
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = self.request.META.get('REMOTE_ADDR',None)
return ip
class SomethingSerializer(serializers.ModelSerializer):
email = serializers.EmailField(validators=[UniqueValidator(queryset=Something.objects.all())])
fieldA = serializers.CharField()
fieldB = serializers.CharField()
class Meta:
model = Customer2
fields = ['email','fieldA','fieldB','ip_addr']
read_only_fields = ['ip_addr']
일반적으로는 「일부러」입니다.request에서 drf는 "drf"입니다.rest_framework.request.Request★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」djangorestframework==3.8.2
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
다음 작업을 수행할 수 있습니다.
request._full_data = your_data
마치 json 끈처럼 생겼네요.이를 딕트로 변환하려면 다음 작업을 수행해야 합니다.
import json
data = json.loads(request.data)
다음으로 Atribut을 추가할 수 있습니다.
data['age'] = 30
그러면 예전 것을 그냥 바꿀 수 없을 것 같아서 새로 요청해야 할 것 같아요.이것은, /notes/: 에 투고하는 것을 전제로 하고 있습니다.
from rest_framework.test import APIRequestFactory
factory = APIRequestFactory()
request = factory.post('/notes/', data, format='json')
요청 오브젝트를 변경할 우려가 있는 경우 상세 복사를 사용하여 오브젝트를 복사하면 쉽게 변경할 수 있습니다.
사용방법:
from copy import deepcopy
# here is your other code and stuffs
data = deepcopy(request.data)
이제 데이터를 자유롭게 변경할 수 있습니다.
지금까지, 이것은 일반적인 관점을 사용하지 않는 한 내가 선호하는 변경 방법입니다.
이 방법의 단점이 있다면 아래에 코멘트를 달아주세요!
Framework)로 되어 있는 DRF(Dango REST Framework)로 되어 있습니다.ViewSet「」를 입니다.to_internal_value이치노
class MyModelViewSet(viewsets.ModelViewSet):
authentication_classes = ...
...
serializer_class = MyModelSerializer
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('id', 'user', ...)
def to_internal_value(self, data):
instance = super(MyModelSerializer, self).to_internal_value(data)
if "lastModified" in data:
# instance["id"] = 10 # That's sketchy though
instance["user"] = "tom"
return instance
코멘트에 의하면:
"게시 전에 API에 필요한 필드 이름 aqs를 확인해야 하기 때문입니다."
'어울리다'를하셔야 합니다.Field대신 의 인수를 사용합니다.
이렇게 하면 오류 메시지의 일관성이 향상됩니다. 그렇지 않으면 사용자가 제공하지 않은 필드 이름의 오류가 발생합니다.
나는 이것을 다르게 다루었다.[ Create ]를 덮어씁니다.API View 생성 메서드는 다음과 같습니다.
class IPAnnotatedObject(CreateAPIView):
model = IPAnnotatedObject
queryset = IPAnnotatedObject.objects.all()
serializer_class = IPAnnotatedObject
def create(self, request, *args, **kwargs):
request.data['ip_addr'] = self.get_ip()
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
## perform_create calls serializer.save() which calls the serializer's create() method
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def get_ip(self):
x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR',None)
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = self.request.META.get('REMOTE_ADDR',None)
return ip
대응하는 시리얼라이저 클래스는 다음과 같습니다.
class IPAnnotatedObjectSerializer(serializers.ModelSerializer):
email = serializers.EmailField(validators=[UniqueValidator(queryset=IPAnnotatedObject.objects.all())])
password = serializers.CharField(write_only=True)
ip_addr = serializers.IPAddressField(write_only=True)
class Meta:
model = IPAnnotatedObject
fields = ['email','password','created_ip']
def create(self, validated_data):
email, password, created_ip = validated_data['email'], validated_data['password'],validated_data['created_ip']
try:
ipAnnoObject = IPAnnotatedObject.objects.create(email=email,password=make_password(password),ip_addr=ip_addr)
except Exception as e:
# you can think of better error handler
pass
return ipAnnoOjbect
다음을 수행했습니다.
import json
data = json.dumps(request.data)
data = json.loads(data)
data['age'] = 100
시점에서 변수 「」를 합니다.datarequest.data.
다른 답변도 좋지만 여기서 한 가지만 덧붙이고 싶었어요.
이제 두 가지 방법으로 업데이트 할 수 있습니다.request.data그러나 그 전에 오브젝트가 QueryDict인지 확인합니다(@mikebridge에서 이미 언급).
from django.http.request import QueryDict
if isInstance(request.data, QueryDict):
request.data._mutable = True
그 후 request.data를 갱신하는 첫 번째 방법은 다음과 같습니다.
request.data.update({'key': 'new_value'})
이것은 정상적으로 동작합니다만, 갱신하는 request.data['key']가 리스트인 경우, 값은 에 의해서 완전하게 변경되지 않습니다.new_value그러나 오래된 목록에 추가되어 문제가 발생할 수 있으며 원하는 결과를 얻지 못할 수 있습니다.
이를 극복하기 위해, 즉 어떤 키의 값을 완전히 변경하려면 두 번째 방법을 사용합니다.
request.data['key'] = 'new_value'
그러면 값이 변경됩니다.request.data['key']에게 완전히new_value.
덮어쓸 수 있음is_validserializer 클래스에서는, 보다 읽기 쉬워집니다.
class YourSerializer
# Don't forget it
age = serializers.IntegerField()
def is_valid(self, raise_exception: bool = ...) -> bool:
self.initial_data["age"] = 30
return super().is_valid(raise_exception)
언급URL : https://stackoverflow.com/questions/33861545/how-can-modify-request-data-in-django-rest-framework
'programing' 카테고리의 다른 글
| AngularJS ng-keydown 디렉티브는 다음 경우에만 동작합니다.AngularJS ng-keydown 디렉티브는 다음 경우에만 동작합니다.콘텍스트를 참조해 주세요.콘텍스트를 참조해 주세요. (0) | 2023.04.01 |
|---|---|
| 특정 어레이 항목 내의 단일 값을 redx로 업데이트하는 방법 (0) | 2023.04.01 |
| 워드프레스에 프로그래밍 방식으로 로그인하는 방법 (0) | 2023.04.01 |
| 결과가 반환되지 않는 경우의 ExecuteScalar() 처리 (0) | 2023.04.01 |
| IE8의 스타일 특성 내에서 AngularJS 식이 작동하지 않습니다. (0) | 2023.04.01 |