জ্যাঙ্গো - কীভাবে একটি ফাইল তৈরি করতে এবং এটি একটি মডেলের ফাইলফিল্ডে সংরক্ষণ করতে?


110

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

class Kitten(models.Model):
    claw_size = ...
    license_file = models.FileField(blank=True, upload_to='license')

    def save(self, *args, **kwargs):
        #Generate a new license file overwriting any previous version
        #and update file path
        self.license_file = ???
        super(Request,self).save(*args, **kwargs)

ফাইল আপলোড করার পদ্ধতি সম্পর্কে আমি প্রচুর ডকুমেন্টেশন দেখছি। তবে আমি কীভাবে একটি ফাইল তৈরি করতে পারি, এটি একটি মডেল ফিল্ডে অর্পণ করব এবং জ্যাঙ্গো এটি সঠিক জায়গায় সঞ্চয় করব?

উত্তর:


152

আপনি জাজানো ডক্সে ফাইলফিল্ড এবং ফিল্ডফাইলে এবং বিশেষত FieldFile.save () এ একবার দেখতে চান

মূলত, FileFieldযখন একটি অ্যাক্সেস করা হয় তখন একটি হিসাবে ঘোষণা করা ক্ষেত্র আপনাকে শ্রেণীর উদাহরণ FieldFileদেয় যা আপনাকে অন্তর্নিহিত ফাইলের সাথে ইন্টারঅ্যাক্ট করার জন্য বিভিন্ন পদ্ধতি দেয়। সুতরাং, আপনার যা করা দরকার তা হ'ল:

self.license_file.save(new_name, new_contents)

new_nameআপনি যে ফাইলের নাম নির্ধারণ করেছেন তা কোথায় এবং new_contentsফাইলটির বিষয়বস্তু। দ্রষ্টব্য যে new_contentsকোনও একটি django.core.files.Fileবা অবশ্যই django.core.files.base.ContentFile(বিশদগুলির জন্য ম্যানুয়ালটিতে প্রদত্ত লিঙ্কগুলি দেখুন) এর উদাহরণ হতে হবে । দুটি পছন্দ নীচে সিদ্ধ:

# Using File
f = open('/path/to/file')
self.license_file.save(new_name, File(f))
# Using ContentFile
self.license_file.save(new_name, ContentFile('A string with the file content'))

1
ঠিক আছে, আমি মনে করি এটি কার্যকর হবে তবে সেভ পদ্ধতিতে আমি এক ধরণের পুনরাবৃত্ত লুপকে কল করছি। এটি কেবল চিরকাল ফাইল তৈরি করে রাখে keeps
গ্রেগ

11
পুনরাবৃত্তির ইস্যুটির জন্য আমাকে self.license_file কল করতে হবে s সংরক্ষণাগারটি সংরক্ষণ করুন = মিথ্যা দিয়ে ave
গ্রেগ

1
এই (কন্টেন্টফাইলে) জাঙ্গো-ডাব্লুএইচটিএমলেটপডিএফ convert_to_pdfকমান্ড দ্বারা ফিরিয়ে দেওয়া ফাইল স্ট্রিংয়ের সাথে পুরোপুরি কাজ করে । ধন্যবাদ!!
নস্টালজ.ইও

এগুলি ছাড়াও, আমি ফাইলটি খোলার সময় যদি আমি ফাইল মোডটি নির্দিষ্ট না করি তবে আমি একটি ত্রুটি পেয়েছি। সুতরাং, f = open('/path/to/file', 'r')জিপ ধরণের ফাইলের জন্য,f = open('/path/to/file.zip', 'rb')
রাজগোপালেক্স

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

28

গৃহীত উত্তর অবশ্যই একটি ভাল সমাধান, তবে আমি এখানে সিএসভি উত্পন্ন করার এবং ভিউ থেকে এটি পরিবেশন করার পথে চলেছি।

ভেবেছি এটি এখানে রাখার সময় মূল্যবান হওয়ায় সমস্ত পছন্দসই আচরণ পেতে আমাকে কিছুটা ফিডিং লেগেছিল (বিদ্যমান ফাইলটি ওভাররাইট করে, সঠিক জায়গায় সংরক্ষণ করা, সদৃশ ফাইল তৈরি করা নয় ইত্যাদি)।

জ্যাঙ্গো 1..৪.২

পাইথন 2.7.3

#Model
class MonthEnd(models.Model):
    report = models.FileField(db_index=True, upload_to='not_used')

import csv
from os.path import join

#build and store the file
def write_csv():
    path = join(settings.MEDIA_ROOT, 'files', 'month_end', 'report.csv')
    f = open(path, "w+b")

    #wipe the existing content
    f.truncate()

    csv_writer = csv.writer(f)
    csv_writer.writerow(('col1'))

    for num in range(3):
        csv_writer.writerow((num, ))

    month_end_file = MonthEnd()
    month_end_file.report.name = path
    month_end_file.save()

from my_app.models import MonthEnd

#serve it up as a download
def get_report(request):
    month_end = MonthEnd.objects.get(file_criteria=criteria)

    response = HttpResponse(month_end.report, content_type='text/plain')
    response['Content-Disposition'] = 'attachment; filename=report.csv'

    return response

1

close()ফাইল সংরক্ষণের প্রক্রিয়া চলাকালীন ব্যতিক্রমের ক্ষেত্রে কোনও প্রসঙ্গে পরিচালক বা কল করা ভাল অনুশীলন । যদি আপনার স্টোরেজ ব্যাকএন্ডটি বন্ধ থাকে তবে ঘটতে পারে etc.

যে কোনও ওভাররাইট আচরণ আপনার স্টোরেজ ব্যাকএন্ডে কনফিগার করা উচিত। উদাহরণস্বরূপ S3Boto3Storage একটি সেটিং আছে AWS_S3_FILE_OVERWRITE। আপনি যদি ব্যবহার করেন তবে FileSystemStorageআপনি একটি কাস্টম মিক্সিন লিখতে পারেন ।

আপনি যদি সর্বশেষ আপডেট হওয়া টাইমস্ট্যাম্পগুলির মতো কোনও কাস্টম-পার্শ্ব প্রতিক্রিয়া ঘটাতে চান তবে আপনি ফাইলফিল্ডের সেভ পদ্ধতির পরিবর্তে মডেলটির সংরক্ষণ পদ্ধতিটি কল করতে চাইতে পারেন। যদি এটি হয় তবে আপনি ফাইলটির নামের সাথে ফাইলটির নাম বৈশিষ্ট্যও সেট করতে পারেন - যা সম্পর্কিত MEDIA_ROOT। এটি ফাইলের সম্পূর্ণ পথে ডিফল্ট হয় যা আপনি এটি সেট না করা হলে সমস্যা দেখা দিতে পারে - ফাইল __ init __ () এবং ফাইল.নাম দেখুন

এখানে এমন একটি উদাহরণ যেখানে selfমডেল উদাহরণ যেখানে my_fileফাইলফিল্ড / ইমেজফিল, save()কেবলমাত্র ফাইলফিল্ডের পরিবর্তে পুরো মডেল উদাহরণটি কল করে:

import os
from django.core.files import File

with open(filepath, 'rb') as fi:
    self.my_file = File(fi, name=os.path.basename(fi.name))
    self.save()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.