इस पर 1 दिन बिताने के बाद, मुझे लगा कि ...
किसी ऐसे व्यक्ति के लिए जिसे किसी फ़ाइल को अपलोड करने और कुछ डेटा भेजने की आवश्यकता है, कोई सीधा fwd तरीका नहीं है जो आप इसे काम करने के लिए प्राप्त कर सकते हैं। इसके लिए json api स्पेक्स में एक खुला मुद्दा है। एक संभावना जिसे मैंने देखा है , multipart/related
जैसा कि यहाँ दिखाया गया है , लेकिन मुझे लगता है कि इसे ड्रॉ में लागू करना बहुत कठिन है।
अंत में मैंने जो लागू किया था वह अनुरोध भेजना था formdata
। आप के रूप में प्रत्येक फ़ाइल भेजना होगा फ़ाइल और पाठ के रूप में अन्य सभी डेटा। अब पाठ के रूप में डेटा भेजने के लिए आपके पास दो विकल्प हैं। केस 1) आप प्रत्येक डेटा को मुख्य मूल्य जोड़ी या केस 2 के रूप में भेज सकते हैं) आपके पास एक एकल कुंजी हो सकती है जिसे डेटा कहा जाता है और पूरे json को स्ट्रिंग के रूप में मूल्य में भेज सकता है।
यदि आपके पास सरल फ़ील्ड हैं, तो पहली विधि बॉक्स से बाहर निकलेगी, लेकिन यदि आपके पास नेस्टेड अनुक्रमित हैं तो यह एक समस्या होगी। मल्टीपार्ट पार्सर अभ्यस्त नेस्टेड फ़ील्ड को पार्स करने में सक्षम है।
नीचे मैं दोनों मामलों के लिए कार्यान्वयन प्रदान कर रहा हूं
Models.py
class Posts(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
caption = models.TextField(max_length=1000)
media = models.ImageField(blank=True, default="", upload_to="posts/")
tags = models.ManyToManyField('Tags', related_name='posts')
serializers.py -> कोई विशेष परिवर्तन की आवश्यकता नहीं है, मेरे क्रम को यहां दिखाने योग्य नहीं है क्योंकि कई माननीय फ़ील्ड के अव्यवस्था के कारण यह बहुत लंबा है।
views.py
class PostsViewset(viewsets.ModelViewSet):
serializer_class = PostsSerializer
#parser_classes = (MultipartJsonParser, parsers.JSONParser) use this if you have simple key value pair as data with no nested serializers
#parser_classes = (parsers.MultipartParser, parsers.JSONParser) use this if you want to parse json in the key value pair data sent
queryset = Posts.objects.all()
lookup_field = 'id'
अब, यदि आप पहली विधि का पालन कर रहे हैं और केवल गैर-जोंस डेटा को मुख्य मूल्य जोड़े के रूप में भेज रहे हैं, तो आपको एक कस्टम पार्सर वर्ग की आवश्यकता नहीं है। DRF'd MultipartParser काम करेगा। लेकिन दूसरे मामले के लिए या यदि आपके पास नेस्टाइज़र हैं (जैसे मैंने दिखाया है) तो आपको कस्टम पार्सर की आवश्यकता होगी जैसा कि नीचे दिखाया गया है।
utils.py
from django.http import QueryDict
import json
from rest_framework import parsers
class MultipartJsonParser(parsers.MultiPartParser):
def parse(self, stream, media_type=None, parser_context=None):
result = super().parse(
stream,
media_type=media_type,
parser_context=parser_context
)
data = {}
# for case1 with nested serializers
# parse each field with json
for key, value in result.data.items():
if type(value) != str:
data[key] = value
continue
if '{' in value or "[" in value:
try:
data[key] = json.loads(value)
except ValueError:
data[key] = value
else:
data[key] = value
# for case 2
# find the data field and parse it
data = json.loads(result.data["data"])
qdict = QueryDict('', mutable=True)
qdict.update(data)
return parsers.DataAndFiles(qdict, result.files)
यह धारावाहिक मूल रूप से मूल्यों में किसी भी json सामग्री को पार्स करेगा।
दोनों मामलों के लिए पोस्ट मैन में अनुरोध उदाहरण: केस 1 ,
केस 2