রানটাইমে নির্ধারিত আপলোড_এর সাথে জাজানো ফাইলফিল্ড


130

আমি আমার আপলোডগুলি সেট আপ করার চেষ্টা করছি যাতে ব্যবহারকারী জো যদি কোনও ফাইল আপলোড করে তবে তা প্রত্যেকের ফাইলকে মিডিয়া_রোটে যাওয়ার বিপরীতে এটি মিডিয়া_রোট / জোতে যায়। সমস্যাটি হ'ল মডেলটিতে এটি কীভাবে সংজ্ঞায়িত করা যায় তা আমি জানি না। এটি বর্তমানে এটি কেমন দেখাচ্ছে:

class Content(models.Model):
    name = models.CharField(max_length=200)
    user = models.ForeignKey(User)
    file = models.FileField(upload_to='.')

সুতরাং আমি যা চাই তা 'পরিবর্তে'। আপলোড_ হিসাবে, এটি ব্যবহারকারীর নাম হবে।

আমি বুঝতে পারি যে জাজানো ১.০ হিসাবে আপনি আপলোড_টি পরিচালনা করতে নিজের ফাংশনটি সংজ্ঞায়িত করতে পারেন তবে ব্যবহারকারীটি কে হবেন সে সম্পর্কে কোনও ফাংশনই জানেন না তাই আমি কিছুটা হারিয়েছি।

সাহায্যের জন্য ধন্যবাদ!

উত্তর:


256

আপনি সম্ভবত দস্তাবেজটি পড়েছেন , সুতরাং এটি বোধ করার জন্য এখানে একটি সহজ উদাহরণ রয়েছে:

def content_file_name(instance, filename):
    return '/'.join(['content', instance.user.username, filename])

class Content(models.Model):
    name = models.CharField(max_length=200)
    user = models.ForeignKey(User)
    file = models.FileField(upload_to=content_file_name)

যেমন আপনি দেখতে পাচ্ছেন, আপনার দেওয়া ফাইলের নামটি ব্যবহার করার দরকার নেই - আপনি যদি পছন্দ করেন তবে আপনার আপলোড_তে কল করতেও এটিকে ওভাররাইড করতে পারেন।


হ্যাঁ, এটি সম্ভবত ডক্সের সাথে সম্পর্কিত - এটি আইআরসি
স্মাইলি ক্রিস

2
এটি মডেলফর্ম নিয়ে কাজ করে? আমি দেখতে পাচ্ছি যে ক্লাস মডেলের সমস্ত বৈশিষ্ট্য রয়েছে এই দৃষ্টান্তে, তবে কোনও মান নেই (ক্ষেত্রের নামের মাত্র একটি স্ট্রিং)। টেমপ্লেটে, ব্যবহারকারী লুকানো আছে। আমাকে কোনও প্রশ্ন জমা দিতে হতে পারে, আমি কয়েক ঘন্টা ধরে এটি গুগল করছি।
মিগ্রাগ

3
অদ্ভুতভাবে যথেষ্ট এটি মূলত এই একই সেটআপে আমার উপর ব্যর্থ হচ্ছে। উদাহরণস্বরূপ ব্যবহারকারীর এতে কোনও বৈশিষ্ট্য নেই।
বব স্প্রিন

11
এটি নন-ইউনিক্স সিস্টেমে কাজ করে তা নিশ্চিত করার os.path.joinপরিবর্তে আপনি এটি ব্যবহার করতে চাইতে পারেন '/'.join। এগুলি বিরল হতে পারে তবে এটি ভাল অনুশীলন;)
Xudonax

2
হাই, আমি একই কোডটি চেষ্টা করেছিলাম, তাদের মডেলগুলিতে রেখেছি py
হ্যারি

12

এটি সত্যিই সাহায্য করেছে। আরও কিছুটা সংক্ষিপ্ততার জন্য, আমার ক্ষেত্রে ল্যাম্বডা ব্যবহার করার সিদ্ধান্ত নিয়েছে:

file = models.FileField(
    upload_to=lambda instance, filename: '/'.join(['mymodel', str(instance.pk), filename]),
)

4
এটি মাইগ্রেশন ব্যবহার করে জাজানো ১.7 এ আমার পক্ষে কাজ করেনি। পরিবর্তে একটি ফাংশন তৈরি আপ শেষ এবং স্থানান্তর গ্রহণ।
aboutaaron

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

2
উদাহরণস্বরূপ pkসংরক্ষণের আগে নেই। এটি কেবল আপডেটের জন্য কাজ করে না ক্রিয়েশন (সন্নিবেশ)।
মোহাম্মদ জাফর মাশহাদি

লাম্বদা migrationsঅপারেশনগুলিতে কাজ করে না কারণ ডক্স
ইব্রাহিম করিমি

4

'উদাহরণস্বরূপ' অবজেক্টের pk মান ব্যবহার করার জন্য একটি নোট। ডকুমেন্টেশন অনুযায়ী:

বেশিরভাগ ক্ষেত্রে, এই অবজেক্টটি এখনও ডাটাবেসে সংরক্ষণ করা হবে না, সুতরাং এটি ডিফল্ট অটোফিল্ড ব্যবহার করে তবে এটির প্রাথমিক কী ক্ষেত্রটির জন্য এখনও কোনও মান থাকতে পারে না।

সুতরাং পিকে ব্যবহারের বৈধতা আপনার নির্দিষ্ট মডেলটি কীভাবে সংজ্ঞায়িত করা হয় তার উপর নির্ভর করে।


আমি মান হিসাবে কিছুই পাচ্ছি। আমি কীভাবে এটি ঠিক করব তা বুঝতে পারি না। আপনি কি কিছুটা বিশদ দিয়ে ব্যাখ্যা করতে পারেন
আমান দীপ

1

মাইগ্রেশনে আপনার যদি সমস্যা হয় তবে আপনার সম্ভবত @deconstructibleডেকরেটর ব্যবহার করা উচিত ।

import datetime
import os
import unicodedata

from django.core.files.storage import default_storage
from django.utils.deconstruct import deconstructible
from django.utils.encoding import force_text, force_str


@deconstructible
class UploadToPath(object):
    def __init__(self, upload_to):
        self.upload_to = upload_to

    def __call__(self, instance, filename):
        return self.generate_filename(filename)

    def get_directory_name(self):
        return os.path.normpath(force_text(datetime.datetime.now().strftime(force_str(self.upload_to))))

    def get_filename(self, filename):
        filename = default_storage.get_valid_name(os.path.basename(filename))
        filename = force_text(filename)
        filename = unicodedata.normalize('NFKD', filename).encode('ascii', 'ignore').decode('ascii')
        return os.path.normpath(filename)

    def generate_filename(self, filename):
        return os.path.join(self.get_directory_name(), self.get_filename(filename))

ব্যবহার:

class MyModel(models.Model):
    file = models.FileField(upload_to=UploadToPath('files/%Y/%m/%d'), max_length=255)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.