জ্যাঙ্গো রেস্ট ফ্রেমওয়ার্ক ফাইল আপলোড


100

আমি ফাইল আপলোড করতে জ্যাঙ্গো রেস্ট ফ্রেমওয়ার্ক এবং অ্যাঙ্গুলারজে ব্যবহার করছি। আমার ভিউ ফাইলটি দেখতে এমন দেখাচ্ছে:

class ProductList(APIView):
    authentication_classes = (authentication.TokenAuthentication,)
    def get(self,request):
        if request.user.is_authenticated(): 
            userCompanyId = request.user.get_profile().companyId
            products = Product.objects.filter(company = userCompanyId)
            serializer = ProductSerializer(products,many=True)
            return Response(serializer.data)

    def post(self,request):
        serializer = ProductSerializer(data=request.DATA, files=request.FILES)
        if serializer.is_valid():
            serializer.save()
            return Response(data=request.DATA)

পোস্ট পদ্ধতির শেষ লাইনে সমস্ত ডেটা ফেরত দেওয়া উচিত, আমার বেশ কয়েকটি প্রশ্ন রয়েছে:

  • কিছু আছে কিনা তা যাচাই করবেন কীভাবে request.FILES?
  • ফাইল ফিল্ড সিরিয়ালাইজ করবেন কীভাবে?
  • আমি কীভাবে পার্সার ব্যবহার করব?

13
মোডের কাছে কেবল একটি নোট: জ্যাঙ্গো ২০১৩ সাল থেকে ব্যাপকভাবে আপগ্রেড হয়েছে So তাই অন্য কেউ যদি এখন একই প্রশ্ন পোস্ট করেন। দয়া করে ^ _ ^ এগুলি গুলি করবেন না ^
জেসি

কিভাবে বেস 64?
হোজাত মোদারেসি

উত্তর:


67

ফাইলআপলোডপার্সার ব্যবহার করুন , এটি সমস্ত অনুরোধে রয়েছে। পরিবর্তে একটি পুট পদ্ধতি ব্যবহার করুন, আপনি ডক্সে একটি উদাহরণ খুঁজে পাবেন :)

class FileUploadView(views.APIView):
    parser_classes = (FileUploadParser,)

    def put(self, request, filename, format=None):
        file_obj = request.FILES['file']
        # do some stuff with uploaded file
        return Response(status=204)

12
@ প্লিজডোনবলগ কেন এখানে পোষ্টের পরিবর্তে পুট পদ্ধতি ব্যবহার করা হয়েছে?
মোঃ তানভীর রায়হান

8
হাই @ প্লিজডন্টবেলং, যদি এটি একটি নতুন রেকর্ড তৈরি করে, তবে কি এটি পরিবর্তে পোস্ট করা হবে? এবং এটি এখনও ফাইলআপলোডপার্সারের সাথে কাজ করবে?
ক্রিজোনলাইন

4
@ প্লিজডন্টবেলং আরটিয়ান একটি খুব ভাল প্রশ্ন জিজ্ঞাসা করছে। আরএফসি -2616 পড়ার ফলে একটি সূক্ষ্মতা পাওয়া যায় যা আমি এখনও অবগত ছিলাম না। "POST এবং PUT অনুরোধগুলির মধ্যে মৌলিক পার্থক্যটি অনুরোধ-ইউআরআই-এর বিভিন্ন অর্থকে প্রতিফলিত করে। একটি পোষ্ট অনুরোধে ইউআরআই সংস্থানিত সত্তাকে পরিচালনা করবে এমন সংস্থানটি সনাক্ত করে That সেই উত্সটি কোনও ডেটা-গ্রহণযোগ্য প্রক্রিয়া, একটি প্রবেশদ্বার হতে পারে কিছু অন্যান্য প্রোটোকল বা কোনো পৃথক অস্তিত্বের টীকা গ্রহণ বিপরীতে কোনো URI লাগাতে অনুরোধ শনাক্ত মধ্যে সত্তা অনুরোধের সাথে ঘিরা "।
dudeman

4
ফাইল আপলোডড পার্সার কেন? "ফাইলআপলোডপার্সার হ'ল দেশীয় ক্লায়েন্টদের সাথে ব্যবহারের জন্য যা ফাইলটিকে কাঁচা ডেটা অনুরোধ হিসাবে আপলোড করতে পারে web ওয়েব-ভিত্তিক আপলোডগুলির জন্য, বা মাল্টিপার্ট আপলোড সমর্থনকারী নেটিভ ক্লায়েন্টদের জন্য, আপনার পরিবর্তে মাল্টিপার্টপার্সার পার্সার ব্যবহার করা উচিত।" সাধারণত একটি ভাল বিকল্প বলে মনে হচ্ছে না। আরও বেশি, ফাইল আপলোডগুলিতে কোনও বিশেষ চিকিত্সার প্রয়োজন দেখছি না ।
এক্স-ইউরি

4
এক্স-ইউুরি দ্বিতীয় স্থানে, ডিআরএফ আমি ফাইলআপলোডপার্সার ব্যবহার করার সময় কনটেন্ট-ডিসপোজিশন শিরোনামটি খালি থাকার বিষয়ে অভিযোগ করে। মাল্টিপার্টপারসার অনেক সহজ, যেহেতু এটি কেবলমাত্র ফাইলের নামটি ফর্ম ক্ষেত্রগুলিতে প্রদত্ত ফাইলের নাম হিসাবে ধরে নিয়েছে।
ডেভিড জওয়ার্ট

74

আমি একই স্ট্যাকটি ব্যবহার করছি এবং ফাইল আপলোডের উদাহরণও সন্ধান করছিলাম, তবে এপিআইভিউয়ের পরিবর্তে মডেলভিউসেট ব্যবহার করার কারণে আমার মামলাটি সহজ। কীটি প্রি_সেভ হুক হিসাবে প্রমাণিত হয়েছিল। আমি এ জাতীয় কৌণিক-ফাইল-আপলোড মডিউলের সাথে এটি ব্যবহার করে শেষ করেছি:

# Django
class ExperimentViewSet(ModelViewSet):
    queryset = Experiment.objects.all()
    serializer_class = ExperimentSerializer

    def pre_save(self, obj):
        obj.samplesheet = self.request.FILES.get('file')

class Experiment(Model):
    notes = TextField(blank=True)
    samplesheet = FileField(blank=True, default='')
    user = ForeignKey(User, related_name='experiments')

class ExperimentSerializer(ModelSerializer):
    class Meta:
        model = Experiment
        fields = ('id', 'notes', 'samplesheet', 'user')

// AngularJS
controller('UploadExperimentCtrl', function($scope, $upload) {
    $scope.submit = function(files, exp) {
        $upload.upload({
            url: '/api/experiments/' + exp.id + '/',
            method: 'PUT',
            data: {user: exp.user.id},
            file: files[0]
        });
    };
});

11
প্রাক_সেভটি ড্রফ 3.x-এ অবহিত করা হয়েছে
গাই এস

আমার অভিজ্ঞতা থেকে, ফাইল ক্ষেত্রগুলির জন্য কোনও বিশেষ চিকিত্সার প্রয়োজন নেই
এক্স-ইউরি

@ গাই-এস, পারফরম্যান্স_ক্রিয়েট, পারফর্ম_আপডেট, পারফরম্যান্স_ডাস্ট্রয়ে পদ্ধতিগুলি পুরানো স্টাইলের সংস্করণ ২.x প্রি-সেভ, পোস্ট_সেভ, প্রি-ডিলিট এবং পোস্ট_ডিলিট পদ্ধতিগুলি এখন আর উপলভ্য নয়: ডিজেঙ্গো-রেস্ট- ফ্রেমওয়ার্ক.org
রুফাত

38

শেষ পর্যন্ত আমি জ্যাঙ্গো ব্যবহার করে চিত্র আপলোড করতে সক্ষম হয়েছি। এখানে আমার কাজের কোড

ভিউ.পি

class FileUploadView(APIView):
    parser_classes = (FileUploadParser, )

    def post(self, request, format='jpg'):
        up_file = request.FILES['file']
        destination = open('/Users/Username/' + up_file.name, 'wb+')
        for chunk in up_file.chunks():
            destination.write(chunk)
        destination.close()  # File should be closed only after all chuns are added

        # ...
        # do some stuff with uploaded file
        # ...
        return Response(up_file.name, status.HTTP_201_CREATED)

urls.py

urlpatterns = patterns('', 
url(r'^imageUpload', views.FileUploadView.as_view())

কার্ল আপলোড করার অনুরোধ

curl -X POST -S -H -u "admin:password" -F "file=@img.jpg;type=image/jpg" 127.0.0.1:8000/resourceurl/imageUpload

14
গন্তব্য.ক্লোজ () লুপের ভিতরে রাখা হয় কেন?
মেকেরজ

12
দেখে মনে হচ্ছে নিবিড়ভাবে ব্যবহার with open('/Users/Username/' + up_file.name, 'wb+') as destination:এবং মুছে ফেলা ভাল হবে
চক উইলবার

এটি ব্যবহার করা সহজ ModelViewSet। এছাড়াও, তারা সম্ভবত এটি আরও ভাল প্রয়োগ করেছে।
এক্স-ইউরি

আমি পুরো দিন ধরে এই উত্তরারের উপর নির্ভর করে চলেছি ... যতক্ষণ না আমি খুঁজে পেয়েছি যে আপনি যখন একাধিক ফাইল আপলোড করতে চান তখন এটির FileUploadParserপ্রয়োজন হয় না, তবে MultiPartParser!
অলিভিয়ার পন্স

13

এটিতে 1 দিন অতিবাহিত করার পরে, আমি বুঝতে পারলাম যে ...

যার জন্য একটি ফাইল আপলোড এবং কিছু ডেটা প্রেরণ করা দরকার, আপনি এটি কাজ করতে পারেন এমন কোনও সোজা fwd উপায় নেই। এটির জন্য জসন এপিআই চশমাগুলিতে একটি উন্মুক্ত সমস্যা রয়েছে। একটি সম্ভাবনা আমি দেখেছি এটি এখানেmultipart/related প্রদর্শিত হিসাবে ব্যবহার করা হয় , তবে আমি মনে করি এটি ড্রাফের মধ্যে প্রয়োগ করা খুব কঠিন।

অবশেষে আমি যা প্রয়োগ করেছি তা হ'ল অনুরোধটি প্রেরণ করা formdata। আপনি যত প্রতিটি ফাইল পাঠাতে হবে ফাইল এবং টেক্সট হিসাবে অন্যান্য সমস্ত ডেটা। পাঠ্য হিসাবে ডেটা প্রেরণের জন্য আপনার দুটি পছন্দ আছে। কেস 1) আপনি প্রতিটি ডেটা কী মান জোড় বা কেস হিসাবে প্রেরণ করতে পারেন 2) আপনার কাছে ডেটা নামক একক কী থাকতে পারে এবং পুরো জেসনকে মান হিসাবে স্ট্রিং হিসাবে প্রেরণ করতে পারেন ।

প্রথম ক্ষেত্রটি যদি আপনার সাধারণ ক্ষেত্রগুলি থাকে তবে বাক্সটি বাইরে চলে আসবে, তবে আপনি সিরিয়ালগুলি নেস্ট করেছেন তবে এটি একটি সমস্যা হবে। গুণিত পার্সার নেস্টেড ক্ষেত্রগুলি পার্স করতে সক্ষম হবে না।

নীচে আমি উভয় ক্ষেত্রেই বাস্তবায়ন সরবরাহ করছি

মডেল.পি

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')

সিরিয়ালাইজার.পি -> কোনও বিশেষ পরিবর্তন দরকার নেই, লেখার যোগ্য ম্যানটোমেনি ফিল্ড ইমপ্লিমেন্টেশনের কারণে এখানে আমার সিরিয়ালটিকে খুব দীর্ঘ হিসাবে দেখানো হচ্ছে না।

ভিউ.পি

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 মাল্টিপার্ট পার্সার কাজটি করবে। তবে দ্বিতীয় ক্ষেত্রে বা আপনার যদি নেস্টেড সিরিয়ালাইজার রয়েছে (যেমন আমি দেখিয়েছি) আপনার নীচের মত কাস্টম পার্সার লাগবে।

Uses.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)

এই সিরিয়ালাইজারটি মূলত মানগুলিতে কোনও জেসন সামগ্রীকে বিশ্লেষণ করবে।

উভয় ক্ষেত্রে পোস্ট ম্যানেলে অনুরোধের উদাহরণ: কেস 1 মামলা 1,

মামলা 2 কেস 2


আমি বরং কেসটি এড়ানো 2 অনুরোধ অনুযায়ী একটি ডাটাবেস রেকর্ড তৈরি করা বেশিরভাগ সময় ঠিক থাকতে হবে fine
এক্স-ইউরি

খুব সহায়ক আপনাকে অনেক ধন্যবাদ তবে আমি বুঝতে পারি না, আপনি কেন ডেকের ডেটা পার্সারে কোয়েরিডিক্টে রূপান্তর করছেন? জাজানোতে আমার ক্ষেত্রে, সাধারণ অভিধানের ডেটা রূপান্তর না করে পুরোপুরি কাজ করে।
মেতেহান গালা

আপনার উল্লিখিত উত্তরটি ব্যবহার করে আমি একটি ভিন্ন দৃশ্যের চেষ্টা করেছি এবং এটি সফলভাবে কাজ করে। আপনি আমার উত্তর তাকান করতে পারেন ।
মেতেহান গোলাপ

এটি যদি স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 4545৪৪772929 /… কাজ করে তবে এটিও কাজ করে।
সাদাত

9

আমার অভিজ্ঞতা থেকে আপনার ফাইল ক্ষেত্র সম্পর্কে বিশেষ কিছু করার দরকার নেই, আপনি কেবল ফাইল ক্ষেত্রটি ব্যবহার করতে বলছেন:

from rest_framework import routers, serializers, viewsets

class Photo(django.db.models.Model):
    file = django.db.models.ImageField()

    def __str__(self):
        return self.file.name

class PhotoSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Photo
        fields = ('id', 'file')   # <-- HERE

class PhotoViewSet(viewsets.ModelViewSet):
    queryset = models.Photo.objects.all()
    serializer_class = PhotoSerializer

router = routers.DefaultRouter()
router.register(r'photos', PhotoViewSet)

api_urlpatterns = ([
    url('', include(router.urls)),
], 'api')
urlpatterns += [
    url(r'^api/', include(api_urlpatterns)),
]

এবং আপনি ফাইল আপলোড করতে প্রস্তুত:

curl -sS http://example.com/api/photos/ -F 'file=@/path/to/file'

যোগ -F field=valueপ্রতিটি অতিরিক্ত ক্ষেত্র আপনার মডেল আছে। ' এবং প্রমাণীকরণ যুক্ত করতে ভুলবেন না।


7

আমি মডেলভিউসেট এবং মডেলশিরাইজার দিয়ে এই সমস্যার সমাধান করেছি। আশা করি এটি সম্প্রদায়কে সহায়তা করবে।

আমি ভেরিফিকেশন এবং অবজেক্ট-> জেএসওএন (এবং তদ্বিপরীত) ভিউয়ের পরিবর্তে সিরিয়ালে নিজেই লগইন করতে পছন্দ করি।

উদাহরণস্বরূপ এটি বুঝতে দেয়।

বলুন, আমি ফাইলআপলোডার এপিআই তৈরি করতে চাই। যেখানে এটি ডাটাবেসে আইডি, ফাইল_পথ, ফাইল_নাম, আকার, মালিক ইত্যাদির মতো ক্ষেত্রগুলি সংরক্ষণ করবে। নীচে নমুনা মডেল দেখুন:

class FileUploader(models.Model):
    file = models.FileField()
    name = models.CharField(max_length=100) #name is filename without extension
    version = models.IntegerField(default=0)
    upload_date = models.DateTimeField(auto_now=True, db_index=True)
    owner = models.ForeignKey('auth.User', related_name='uploaded_files')
    size = models.IntegerField(default=0)

এখন, এপিআইগুলির জন্য এটি আমি যা চাই:

  1. পাওয়া:

আমি যখন জিইটি শেষ পয়েন্টটি ফায়ার করি, আমি প্রতিটি আপলোড করা ফাইলের জন্য উপরের ক্ষেত্রগুলি চাই।

  1. পোস্ট:

তবে ব্যবহারকারী ফাইল তৈরি / আপলোড করার জন্য কেন তাকে এই সমস্ত ক্ষেত্রটি পাস করার বিষয়ে চিন্তা করতে হবে। তিনি কেবল ফাইলটি আপলোড করতে পারেন এবং তারপরে আমার ধারণা, সিরিয়ালাইজার আপলোড করা ফাইল থেকে বাকী ক্ষেত্রগুলি পেতে পারে।

সিলিলাইজার: প্রশ্ন: আমি আমার উদ্দেশ্যটি পরিবেশন করতে নীচে সিরিয়াল তৈরি করেছি। তবে এটি কার্যকর করার সঠিক উপায় কিনা তা নিশ্চিত নন।

class FileUploaderSerializer(serializers.ModelSerializer):
    # overwrite = serializers.BooleanField()
    class Meta:
        model = FileUploader
        fields = ('file','name','version','upload_date', 'size')
        read_only_fields = ('name','version','owner','upload_date', 'size')

   def validate(self, validated_data):
        validated_data['owner'] = self.context['request'].user
        validated_data['name'] = os.path.splitext(validated_data['file'].name)[0]
        validated_data['size'] = validated_data['file'].size
        #other validation logic
        return validated_data

    def create(self, validated_data):
        return FileUploader.objects.create(**validated_data)

রেফারেন্সের জন্য ভিউসেট:

class FileUploaderViewSet(viewsets.ModelViewSet):
    serializer_class = FileUploaderSerializer
    parser_classes = (MultiPartParser, FormParser,)

    # overriding default query set
    queryset = LayerFile.objects.all()

    def get_queryset(self, *args, **kwargs):
        qs = super(FileUploaderViewSet, self).get_queryset(*args, **kwargs)
        qs = qs.filter(owner=self.request.user)
        return qs

FileUploaderSerializer.validateপদ্ধতিতে কোন বৈধতা যুক্তি থাকতে পারে?
এক্স-ইউরি

6

জ্যাঙ্গো রেস্ট ফ্রেমওয়ার্কের জন্য মডেলভিউসেটের সাথে সবচেয়ে সহজ উদাহরণটিতে আগ্রহী যদি কেউ।

মডেলটি হ'ল,

class MyModel(models.Model):
    name = models.CharField(db_column='name', max_length=200, blank=False, null=False, unique=True)
    imageUrl = models.FileField(db_column='image_url', blank=True, null=True, upload_to='images/')

    class Meta:
        managed = True
        db_table = 'MyModel'

সিরিয়ালাইজার,

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = "__all__"

এবং দর্শনটি হ'ল,

class MyModelView(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

পোস্টম্যানে পরীক্ষা,

এখানে চিত্র বর্ণনা লিখুন


এবং কীভাবে আমরা এজ্যাক্স ব্যবহার করে অনুরোধটি প্রেরণ করতে পারি। ইমেজআরল আসলে কী?
এডুয়ার্ড গ্রিগরিয়েভ

ইমেজ ইউআরএল অনুরোধের ফাইল।
সাদাত


0

জাঙ্গো-বিশ্রাম-কাঠামোর অনুরোধের ডেটা দ্বারা পার্স করা হয় Parsers
http://www.django-rest-framework.org/api-guide/parsers/

ডিফল্টরূপে জাঙ্গো-রেস্ট-ফ্রেমওয়ার্ক পার্সার ক্লাস নেয় JSONParser। এটি জসনের মধ্যে ডেটা পার্স করবে। সুতরাং, ফাইলগুলি এর সাথে বিশ্লেষণ করা হবে না।
আমরা যদি অন্য ডেটার সাথে ফাইলগুলি বিশ্লেষণ করতে চাই তবে আমাদের নীচের পার্সার ক্লাসগুলির একটি ব্যবহার করা উচিত।

FormParser
MultiPartParser
FileUploadParser

ডিআরএফ 3.8.2 এর বর্তমান সংস্করণে এটি ডিফল্টরূপে , এবং application/json, বিশ্লেষণ করবে । application/x-www-form-urlencodedmultipart/form-data
তরলকি

0
    from rest_framework import status
    from rest_framework.response import Response
    class FileUpload(APIView):
         def put(request):
             try:
                file = request.FILES['filename']
                #now upload to s3 bucket or your media file
             except Exception as e:
                   print e
                   return Response(status, 
                           status.HTTP_500_INTERNAL_SERVER_ERROR)
             return Response(status, status.HTTP_200_OK)

0

আমি অন্য একটি বিকল্প লিখতে চাই যা আমি মনে করি এটি পরিষ্কার এবং বজায় রাখা সহজ। আমরা আমাদের ভিউসেটের জন্য সিআরইউডি ইউআরএল যোগ করতে ডিফল্টরউটারটি ব্যবহার করব এবং আমরা একই ভিউসেটের মধ্যে আপলোডার ভিউ নির্দিষ্ট করে আরও একটি নির্দিষ্ট url যুক্ত করব।

**** views.py 

from rest_framework import viewsets, serializers
from rest_framework.decorators import action, parser_classes
from rest_framework.parsers import JSONParser, MultiPartParser
from rest_framework.response import Response
from rest_framework_csv.parsers import CSVParser
from posts.models import Post
from posts.serializers import PostSerializer     


class PostsViewSet(viewsets.ModelViewSet):

    queryset = Post.objects.all()
    serializer_class = PostSerializer 
    parser_classes = (JSONParser, MultiPartParser, CSVParser)


    @action(detail=False, methods=['put'], name='Uploader View', parser_classes=[CSVParser],)
    def uploader(self, request, filename, format=None):
        # Parsed data will be returned within the request object by accessing 'data' attr  
        _data = request.data

        return Response(status=204)

প্রকল্পের প্রধান urls.py

**** urls.py 

from rest_framework import routers
from posts.views import PostsViewSet


router = routers.DefaultRouter()
router.register(r'posts', PostsViewSet)

urlpatterns = [
    url(r'^posts/uploader/(?P<filename>[^/]+)$', PostsViewSet.as_view({'put': 'uploader'}), name='posts_uploader')
    url(r'^', include(router.urls), name='root-api'),
    url('admin/', admin.site.urls),
]

.- পড়ুন।

যাদুটি তখন ঘটে যখন আমরা আমাদের ক্লাস পদ্ধতিতে 'আপলোডার' এ @ অ্যাকশন ডেকরেটর যুক্ত করি। "পদ্ধতিগুলি = ['পুট']" আর্গুমেন্ট নির্দিষ্ট করে, আমরা কেবল PUT অনুরোধের অনুমতি দিচ্ছি; ফাইল আপলোড করার জন্য নিখুঁত।

আপনি "পার্সার_ক্ল্যাশগুলি" যুক্তি যুক্ত করে দেখিয়েছেন যে আপনি যে পার্সারটি আপনার সামগ্রীকে বিশ্লেষণ করতে পারবেন তা নির্বাচন করতে পারেন। আমি রেস্ট_ফ্রেমওয়ার্ক_সিএসভি প্যাকেজ থেকে CSVParser যুক্ত করেছি, এই কার্যকারিতাটির প্রয়োজন হলে আমরা কেবলমাত্র নির্দিষ্ট ধরণের ফাইলগুলি কীভাবে গ্রহণ করতে পারি তা প্রদর্শনের জন্য, আমার ক্ষেত্রে আমি কেবল "সামগ্রী-প্রকার: পাঠ্য / সিএসভি" গ্রহণ করছি। দ্রষ্টব্য: আপনি যদি কাস্টম পার্সার যুক্ত করছেন, আপলোডার পদ্ধতি পার্সার্স অ্যাক্সেস করার আগে আপনাকে অনুরোধটির কারণে ভিউসেটে পার্সার_ক্লাসগুলিতে নির্দিষ্ট করতে হবে main

এখন আমাদের জাঙ্গোকে এই পদ্ধতিতে কীভাবে যেতে হবে এবং কোথায় আমাদের ইউআরএলগুলিতে প্রয়োগ করা যেতে পারে তা জানাতে হবে। এটি যখন আমরা স্থির ইউআরএল (সাধারণ উদ্দেশ্য) যুক্ত করি। এই url একটি "ফাইল নাম" যুক্তি নেবে যা পরে পদ্ধতিতে পাস করা হবে। আমাদের এই পদ্ধতিটি "আপলোডার" পাস করতে হবে, পোস্ট ভিউসেট.অ্যাস_ভিউ পদ্ধতিতে একটি তালিকায় HTTP প্রোটোকল ('PUT') নির্দিষ্ট করে।

আমরা যখন নিম্নলিখিত url এ অবতরণ করি

 http://example.com/posts/uploader/ 

এটি "সামগ্রী-প্রকার" এবং সামগ্রী-বিশৃঙ্খলা উল্লেখ করে শিরোনামগুলির সাথে একটি PUT অনুরোধ আশা করবে: সংযুক্তি; ফাইলের নাম = "কিছুর সিএসভি"।

curl -v -u user:pass http://example.com/posts/uploader/ --upload-file ./something.csv --header "Content-type:text/csv"

সুতরাং আপনি কোনও ফাইল আপলোড করার পরামর্শ দিচ্ছেন, তারপরে এটি কিছু ডিবি রেকর্ডের সাথে সংযুক্ত করুন। যদি সংযুক্তি কোনও কারণে কখনও ঘটে না তবে কী হবে? কেন এক অনুরোধে তা করবেন না? parser_classesকোন ফাইল আপলোড করা যেতে পারে তা সীমাবদ্ধ করার জন্য নেই। এটি আপনাকে সিদ্ধান্ত নিতে দেয় যে অনুরোধগুলি করতে কোন ফর্ম্যাটগুলি ব্যবহার করা যেতে পারে। দ্বিতীয় চিন্তায়, আপনি যেভাবে আপলোডটি পরিচালনা করবেন ... মনে হচ্ছে আপনি সিএসভি থেকে ডেটাবেসে ডেটা রাখছেন। ওপি যা চেয়েছিল তা নয়।
এক্স-ইউরি

@ x-yuri "একটি সিএসভি একটি ফাইল" বলে এবং প্রশ্নটি হল; অনুরোধে ডেটা আছে কিনা তা কীভাবে পরীক্ষা করবেন? এই পদ্ধতিটি ব্যবহার করে, আপনি অনুরোধ.ডাটাতে ডেটা পাবেন। _ডাটা = অনুরোধ.প্যাটের কারণে ডেটা ব্যবহৃত হচ্ছে। আপনি যেমন বলেছিলেন, পার্সার_ক্ল্যাসিসগুলি ঠিক আছে যে কোন ফর্ম্যাটগুলির জন্য অনুরোধ করার জন্য আপনি যে অন্য বিন্যাসটি চান না তা ব্যবহার করার জন্য ব্যবহার করা যেতে পারে, তারপরে সুরক্ষার অতিরিক্ত স্তর যুক্ত করে বাদ দেওয়া হবে। আপনার ডেটা দিয়ে আপনি কী করবেন তা আপনার উপর নির্ভর করে। "ব্যতীত চেষ্টা করুন" ব্যবহার করে আপনি "সংযুক্তি কখনই ঘটে না" কিনা তা পরীক্ষা করে দেখতে পারেন যে কোডটির কোনও প্রয়োজন নেই, এটির কোনও প্রয়োজন নেই। এগুলি 1 টি অনুরোধে তৈরি করা হয়েছে
ওল্ফগাং লিওন

0

আশা করি এটি প্রয়োগের একটি এটি আশা করি এটি সাহায্য করবে।

     class Model_File_update(APIView):
         parser_classes = (MultiPartParser, FormParser)
         permission_classes = [IsAuthenticated]  # it will check if the user is authenticated or not
         authentication_classes = [JSONWebTokenAuthentication]  # it will authenticate the person by JSON web token

         def put(self, request):
            id = request.GET.get('id')
            obj = Model.objects.get(id=id)
            serializer = Model_Upload_Serializer(obj, data=request.data)
            if serializer.is_valid():
               serializer.save()
               return Response(serializer.data, status=200)
            else:
               return Response(serializer.errors, status=400)

0

আপনি সরাসরি ডিআরএফের সিরিয়ালাইজারগুলিতে সরাসরি খাওয়ানো হয় এমন নির্দিষ্ট ক্ষেত্রগুলিকে পার্স করার জন্য পার্সার শ্রেণি তৈরি করে ডিআরএফ এর বিদ্যমান সিরিয়ালাইজার সিস্টেমের সাথে সরাসরি কাজ করার জন্য @ নীথিনের জবাবকে সাধারণ করতে পারেন:

from django.http import QueryDict
import json
from rest_framework import parsers


def gen_MultipartJsonParser(json_fields):
    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 = {}
            # find the data field and parse it
            qdict = QueryDict('', mutable=True)
            for json_field in json_fields:
                json_data = result.data.get(json_field, None)
                if not json_data:
                    continue
                data = json.loads(json_data)
                if type(data) == list:
                    for d in data:
                        qdict.update({json_field: d})
                else:
                    qdict.update({json_field: data})

            return parsers.DataAndFiles(qdict, result.files)

    return MultipartJsonParser

এটি এর মতো ব্যবহৃত হয়:

class MyFileViewSet(ModelViewSet):
    parser_classes = [gen_MultipartJsonParser(['tags', 'permissions'])]
    #                                           ^^^^^^^^^^^^^^^^^^^
    #                              Fields that need to be further JSON parsed
    ....

0

আপনি যদি মডেলভিউসেট ব্যবহার করেন, তবে আসলে আপনি শেষ করেছেন! এটি আপনার জন্য প্রতিটি জিনিস পরিচালনা করে! আপনার কেবলমাত্র ক্ষেত্রটি আপনার মডেলশিরাইজারে রেখে content-type=multipart/form-data;আপনার ক্লায়েন্টে সেট করা দরকার ।

তবে আপনি জানেন যে আপনি ফাইলগুলি জসন ফর্ম্যাটে প্রেরণ করতে পারবেন না। (যখন আপনার ক্লায়েন্টে কন্টেন্ট-টাইপ অ্যাপ্লিকেশন / জেসন সেট করা থাকে)। আপনি বেস 64 ফর্ম্যাটটি ব্যবহার না করেই।

সুতরাং আপনার দুটি পছন্দ আছে:

  • দিন ModelViewSetএবং ModelSerializerকাজ হ্যান্ডেল এবং ব্যবহার অনুরোধ পাঠাতেcontent-type=multipart/form-data;
  • ModelSerializerহিসাবে ক্ষেত্রটি সেট করুন Base64ImageField (or) Base64FileFieldএবং আপনার ক্লায়েন্টকে ফাইলটি এনকোড করতে Base64এবং সেট করতে বলুনcontent-type=application/json

0

মডেল.পি

from django.db import models

import uuid

class File(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    file = models.FileField(blank=False, null=False)
    
    def __str__(self):
        return self.file.name

সিরিয়ালাইজার.পি

from rest_framework import serializers
from .models import File

class FileSerializer(serializers.ModelSerializer):
    class Meta:
        model = File
        fields = "__all__"

ভিউ.পি

from django.shortcuts import render
from rest_framework.parsers import FileUploadParser
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status

from .serializers import FileSerializer


class FileUploadView(APIView):
    permission_classes = []
    parser_class = (FileUploadParser,)

    def post(self, request, *args, **kwargs):

      file_serializer = FileSerializer(data=request.data)

      if file_serializer.is_valid():
          file_serializer.save()
          return Response(file_serializer.data, status=status.HTTP_201_CREATED)
      else:
          return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

urls.py

from apps.files import views as FileViews

urlpatterns = [
    path('api/files', FileViews.FileUploadView.as_view()),
]

সেটিংস.পি

# file uload parameters
MEDIA_URL =  '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

api/filesকোনও form-dataক্ষেত্রের সাথে সংযুক্ত আপনার ফাইলের সাথে একটি পোস্টের অনুরোধ প্রেরণ করুন file। ফাইলটি /mediaফোল্ডারে আপলোড করা হবে এবং আইডি এবং ফাইলের নামের সাথে একটি ডিবি রেকর্ড যুক্ত হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.