Django - एक फ़ाइल कैसे बनाएं और इसे किसी मॉडल के FileField में कैसे सहेजें?


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)

मैं फ़ाइल अपलोड करने के तरीके के बारे में बहुत सारे दस्तावेज़ देखता हूँ। लेकिन मैं एक फ़ाइल कैसे उत्पन्न करूं, इसे एक मॉडल फ़ील्ड में असाइन करूं और Django को इसे सही स्थान पर संग्रहीत करूं?

जवाबों:


152

आप Django डॉक्स और विशेष रूप से FieldFile.save () में FileField और FieldFile पर एक नज़र रखना चाहते हैं ।

मूल रूप से, एक क्षेत्र के रूप में घोषित किया गया है 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
ठीक है, मुझे लगता है कि काम करेगा, लेकिन मैं किसी तरह के पुनरावर्ती लूप में मिल रहा हूं जो कि बचत विधि में है। यह बस हमेशा के लिए फाइल बनाता रहता है।
ग्रेग

11
पुनरावर्ती मुद्दे के लिए मुझे आर्ग सेव = गलत के साथ self.license_file.save को कॉल करना होगा।
ग्रेग

1
यह (ContentFile) django-wkhtmltopdf के convert_to_pdfकमांड द्वारा लौटाए गए फ़ाइल स्ट्रिंग के साथ पूरी तरह से काम करता है । धन्यवाद!!
4

इसके अतिरिक्त, यदि मुझे फ़ाइल खोलते समय फ़ाइल मोड निर्दिष्ट नहीं होता है, तो मुझे एक त्रुटि मिली। तो, f = open('/path/to/file', 'r')f = open('/path/to/file.zip', 'rb')
जिप

1
मेरे मामले में, उपरोक्त फ़ाइल को फ़ोल्डर में सहेज नहीं रहा था। इस मुद्दे को बदल दिया जाता है कि मैं एक अजवाइन कार्यकर्ता के साथ अपने django ऐप को चलाने के लिए docker- रचना का उपयोग कर रहा हूं । MEDIA_ROOTअजवाइन कार्यकर्ता में समान मात्रा के साथ django ऐप वॉल्यूम साझा नहीं किया गया था। नामित मात्रा को साझा करते हुए इसे ( रेफ ) निर्धारित किया गया ।
छाया

28

स्वीकृत उत्तर निश्चित रूप से एक अच्छा समाधान है, लेकिन यहाँ जिस तरह से मैं एक सीएसवी उत्पन्न करने और इसे एक दृश्य से सेवा देने के बारे में गया था।

सोचा था कि इसे यहां डालते समय लायक था क्योंकि यह मुझे सभी वांछनीय व्यवहार (मौजूदा फाइल को अधिलेखित करने, सही स्थान पर संग्रहीत करने, डुप्लिकेट फ़ाइलों का निर्माण नहीं करने आदि) के लिए थोड़ा सा फ़िदा हुआ।

Django 1.4.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()फ़ाइल बचत प्रक्रिया के दौरान अपवादों के मामले में संदर्भ प्रबंधक का उपयोग करना या कॉल करना अच्छा है। यदि आपका स्टोरेज बैकेंड डाउन है, आदि हो सकता है।

किसी भी अधिलेखित व्यवहार को आपके संग्रहण बैकेंड में कॉन्फ़िगर किया जाना चाहिए। उदाहरण के लिए S3Boto3Storage की एक सेटिंग है AWS_S3_FILE_OVERWRITE। यदि आप उपयोग कर रहे हैं तो आप FileSystemStorageएक कस्टम मिक्सिन लिख सकते हैं ।

यदि आप किसी भी कस्टम साइड-इफेक्ट को होने देना चाहते हैं, तो आप फाइलफीड के सेव विधि के बजाय मॉडल की सेव विधि को कॉल कर सकते हैं। यदि ऐसा है, तो आप फ़ाइल के नाम की विशेषता को फ़ाइल के नाम पर भी सेट कर सकते हैं - जो सापेक्ष है MEDIA_ROOT। यह फ़ाइल के पूर्ण पथ पर डिफॉल्ट करता है जो आपके द्वारा सेट न किए जाने पर समस्याएँ पैदा कर सकता है - फ़ाइल .__ init __ () और File.name देखें

यहाँ एक उदाहरण है कि फ़ाइल का फ़ाइल / ImageFile 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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.