Bunun için 1 gün geçirdikten sonra anladım ki ...
Bir dosya yüklemesi ve bazı verileri göndermesi gereken biri için, onu çalıştırmanın doğrudan bir yolu yoktur. Bunun için json api özelliklerinde açık bir sorun var . Gördüğüm bir olasılık, buradamultipart/related
gösterildiği gibi kullanmak , ancak bence bunu drf'de uygulamak çok zor.
Sonunda uyguladığım şey, isteği olarak göndermekti formdata
. Sen her dosyayı göndereceği dosyanın ve metin gibi tüm diğer veriler. Şimdi verileri metin olarak göndermek için iki seçeneğiniz var. durum 1) her veriyi anahtar değer çifti olarak gönderebilir veya durum 2) veri adı verilen tek bir anahtara sahip olabilir ve tüm json'u değer dizisi olarak gönderebilirsiniz.
İlk yöntem, basit alanlarınız varsa kutudan çıkar, ancak iç içe serileştirmeleriniz varsa bir sorun olacaktır. Çok parçalı ayrıştırıcı, iç içe geçmiş alanları ayrıştıramaz.
Aşağıda her iki durum için de uygulama sağlıyorum
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 -> özel bir değişikliğe gerek yok, yazılabilir ManyToMany Field uygulaması nedeniyle burada serileştiricimi çok uzun olarak göstermiyorum.
views.py
class PostsViewset(viewsets.ModelViewSet):
serializer_class = PostsSerializer
queryset = Posts.objects.all()
lookup_field = 'id'
Şimdi, ilk yöntemi takip ediyorsanız ve yalnızca anahtar değer çiftleri olarak Json olmayan verileri gönderiyorsanız, özel bir ayrıştırıcı sınıfına ihtiyacınız yoktur. DRF’li MultipartParser işi yapacak. Ancak ikinci durum için veya iç içe diziselleştiricileriniz varsa (gösterdiğim gibi), aşağıda gösterildiği gibi özel ayrıştırıcıya ihtiyacınız olacaktır.
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 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
data = json.loads(result.data["data"])
qdict = QueryDict('', mutable=True)
qdict.update(data)
return parsers.DataAndFiles(qdict, result.files)
Bu serileştirici, temelde değerlerdeki herhangi bir json içeriğini ayrıştırır.
Her iki durum için post man'daki istek örneği: vaka 1 ,
Durum 2