জাঙ্গো: চিত্র url থেকে একটি চিত্রফিল্ডে চিত্র যুক্ত করুন


86

দয়া করে আমার কুরুচিপূর্ণ ইংরেজির জন্য আমাকে ক্ষমা করুন ;-)

খুব সাধারণ মডেলটি কল্পনা করুন:

class Photo(models.Model):
    image = models.ImageField('Label', upload_to='path/')

আমি কোনও চিত্রের ইউআরএল (যেমন, জাঙ্গো অ্যাডমিন সাইটে হাতে হাতে নয়) থেকে একটি ফটো তৈরি করতে চাই।

আমার মনে হয় এরকম কিছু করার দরকার আছে:

from myapp.models import Photo
import urllib

img_url = 'http://www.site.com/image.jpg'
img = urllib.urlopen(img_url)
# Here I need to retrieve the image (as the same way that if I put it in an input from admin site)
photo = Photo.objects.create(image=image)

আমি আশা করি যে আমি সমস্যাটি ভালভাবে ব্যাখ্যা করেছি, যদি না বলুন।

ধন্যবাদ :)

সম্পাদনা করুন:

এটি কাজ করতে পারে তবে আমি জানিনা কীভাবে contentজাঙ্গো ফাইলে রূপান্তর করতে হবে:

from urlparse import urlparse
import urllib2
from django.core.files import File

photo = Photo()
img_url = 'http://i.ytimg.com/vi/GPpN5YUNDeI/default.jpg'
name = urlparse(img_url).path.split('/')[-1]
content = urllib2.urlopen(img_url).read()

# problem: content must be an instance of File
photo.image.save(name, content, save=True)

উত্তর:


96

আমি এই একই সমস্যার জন্য সবেমাত্র http://www.djangosnippets.org/snippets/1890/ তৈরি করেছি । কোডটি উপরের পাইথলেস জবাবের সমান যেমন এটি urllib2.urlopen ব্যবহার না করে কারণ urllib.urlretrieve ডিফল্টরূপে কোনও ত্রুটি পরিচালনার কাজ করে না সুতরাং আপনার প্রয়োজনের পরিবর্তে 404/500 পৃষ্ঠার সামগ্রীগুলি পাওয়া সহজ। আপনি কলব্যাক ফাংশন এবং কাস্টম ইউআরএল ওপেনার সাবক্লাস তৈরি করতে পারেন তবে আমার নিজের টেম্প ফাইলটি কেবল এটির মতো তৈরি করা সহজ হয়েছে:

from django.core.files import File
from django.core.files.temp import NamedTemporaryFile

img_temp = NamedTemporaryFile(delete=True)
img_temp.write(urllib2.urlopen(url).read())
img_temp.flush()

im.file.save(img_filename, File(img_temp))

4
শেষ লাইনটি কি করছে? কি imজিনিস থেকে আসছে?
পুরোহিত

4
@ প্রাইস্টক: imকিছুটা ক্ষুদ্র ছিল - উদাহরণস্বরূপ, এটি imছিল মডেল উদাহরণ এবং fileসেই উদাহরণটিতে একটি ফাইলফিল্ড / চিত্রফিল্ডের অকল্পনীয় নাম ছিল। এখানে আসল এপিআই ডক্স যা গুরুত্বপূর্ণ - সেই কৌশলটি আপনার যে কোনও জায়গায় জ্যাঙ্গো ফাইল অবজেক্টের সাথে আবদ্ধ থাকতে হবে যেখানে কাজ করা উচিত: ডকস.ডজ্যাঙ্গোপ্রজেক্ট
ক্রিস অ্যাডামস

27
একটি অস্থায়ী ফাইল অপ্রয়োজনীয়। requestsপরিবর্তে urllib2আপনি ব্যবহার করতে পারেন: image_content = ContentFile(requests.get(url_image).content)এবং তারপরে obj.my_image.save("foo.jpg", image_content)
স্ট্যান

স্ট্যান: অনুরোধগুলি সরল করে তবে আইআইআরসি যে ওয়ান-লাইনার একটি সমস্যা হবে যদি না আপনি ত্রুটি বা অসম্পূর্ণ প্রতিক্রিয়াগুলির সাথে বিভ্রান্তি এড়াতে প্রথমে উত্সাহিত্য_স্ট্যাটাস () না বলে থাকেন
ক্রিস অ্যাডামস

এটি আধুনিকীকরণ করা সম্ভবত একটি ভাল ধারণা হবে কারণ এটি মূলত জ্যাঙ্গো ১.১ / ১.২-এর যুগে লেখা হয়েছিল। এটি বলেছিল, আমি বিশ্বাস করি যে কন্টেন্টফাইলে এখনও সমস্যা রয়েছে যে এটি পুরো ফাইলটিকে মেমরিতে লোড করবে তাই একটি দুর্দান্ত অপ্টিমাইজেশন যুক্তিসঙ্গত আকারের সাথে এটির_কন্টেন্ট ব্যবহার করবে।
ক্রিস অ্যাডামস

32

from myapp.models import Photo
import urllib
from urlparse import urlparse
from django.core.files import File

img_url = 'http://www.site.com/image.jpg'

photo = Photo()    # set any other fields, but don't commit to DB (ie. don't save())
name = urlparse(img_url).path.split('/')[-1]
content = urllib.urlretrieve(img_url)

# See also: http://docs.djangoproject.com/en/dev/ref/files/file/
photo.image.save(name, File(open(content[0])), save=True)


হাই, আমাকে সাহায্য করার জন্য আপনাকে ধন্যবাদ;)। সমস্যাটি হ'ল (আমি দস্তাবেজের উদ্ধৃতি দিয়েছি): "নোট করুন যে বিষয়বস্তু যুক্তিটি অবশ্যই ফাইলের বা ফাইলের উপক্লাসের একটি উদাহরণ হতে হবে" " তাহলে আপনার সামগ্রীতে ফাইল ইনস্ট্যান্স তৈরির কোনও সমাধান আছে কি?

নতুন সম্পাদনা পরীক্ষা করুন; এটি এখন একটি কাজের উদাহরণ হতে হবে (যদিও আমি এটি পরীক্ষা করি নি)
পাইথলেস

আমার মডেল সম্পর্কে, যেখানে আমার অন্যান্য ক্ষেত্রগুলিও রয়েছে। ইউআরএল ইত্যাদির মতো আইডি যদি মডেল.ইমেজ.স্যাভ (...) করেন। আমি অন্যান্য ক্ষেত্রগুলি কীভাবে সংরক্ষণ করব? এগুলি শূন্য করা যাবে না সম্পাদনা: এটি কি এমন কিছু হতে পারে? >>> car.photo.save ('myphoto.jpg', বিষয়বস্তু, সংরক্ষণ = মিথ্যা) >>> car.save ()
হ্যারি

সেল্ফ.আরল ?? ... এখানে সেলফআরল কি ??
ডেডড্যাজ্যাঙ্গো জোকার

@ ডেডডাজ্যাঙ্গোডোকার কোনও ধারণা নেই, আপনি যে আমার উত্তর সম্পাদনা করেছেন তাকে জিজ্ঞাসা করতে হবে। এই উত্তরটি এই সময়ে 5 বছরের পুরানো; উত্তরোত্তর জন্য আমি পূর্ববর্তী "কার্যকরী" সমাধানটিতে ফিরে এসেছি, তবে সত্যি কথা বলতে আপনি ক্রিস অ্যাডামের উত্তরটি দিয়ে আরও ভাল।
নির্মম

13

ক্রিস অ্যাডামস এবং স্ট্যান যা বলেছিল তার সাথে মিশ্রিত করা এবং পাইথন 3 এ কাজ করার জন্য জিনিসগুলি আপডেট করা, আপনি যদি অনুরোধগুলি ইনস্টল করেন আপনি এই জাতীয় কিছু করতে পারেন:

from urllib.parse import urlparse
import requests
from django.core.files.base import ContentFile
from myapp.models import Photo

img_url = 'http://www.example.com/image.jpg'
name = urlparse(img_url).path.split('/')[-1]

photo = Photo() # set any other fields, but don't commit to DB (ie. don't save())

response = requests.get(img_url)
if response.status_code == 200:
    photo.image.save(name, ContentFile(response.content), save=True)

জ্যাঙ্গোর কনটেন্টফিল ডকুমেন্টেশন এবং অনুরোধগুলির ফাইল ডাউনলোড উদাহরণে আরও প্রাসঙ্গিক ডক্স ।


5

ImageFieldকেবল একটি স্ট্রিং, আপনার MEDIA_ROOTসেটিংয়ের সাথে সম্পর্কিত path কেবল ফাইলটি সংরক্ষণ করুন (আপনি এটি চিত্রের চেক করতে পিআইএল ব্যবহার করতে চাইতে পারেন) এবং ফাইলটির সাথে ফিল্ডটি পপুলেট করুন।

সুতরাং এটি আপনার কোড থেকে পৃথক যে আপনাকে urllib.urlopenফাইলের আউটপুট সংরক্ষণ করতে হবে (আপনার মিডিয়া অবস্থানের অভ্যন্তরে), পথটি কার্যকর করুন, এটি আপনার মডেলটিকে সংরক্ষণ করুন।


5

আমি পাইথন 3 এ এটি করি, যা পাইথন 2 এ সাধারণ অভিযোজনগুলির সাথে কাজ করা উচিত This এটি আমার জ্ঞানের উপর ভিত্তি করে আমি যে ফাইলগুলি পুনরুদ্ধার করছি তা ছোট। যদি আপনার না হয় তবে আমি সম্ভবত মেমরির বাফারিংয়ের পরিবর্তে কোনও ফাইলটিতে প্রতিক্রিয়া লেখার পরামর্শ দেব।

বাইটসআইও প্রয়োজন কারণ জ্যাঙ্গো ফাইল অবজেক্টে () সিক () কল করে এবং urlopen প্রতিক্রিয়াগুলি অনুসন্ধানকে সমর্থন করে না। আপনি এর পরিবর্তে জ্যাঙ্গোর কনটেন্টফাইলে () পড়ে বাইটস বস্তুটি পাস করতে পারেন।

from io import BytesIO
from urllib.request import urlopen

from django.core.files import File


# url, filename, model_instance assumed to be provided
response = urlopen(url)
io = BytesIO(response.read())
model_instance.image_field.save(filename, File(io))

ফাইল (io) <ফাইল: কিছুই নেই>
সুসাজ এস নায়ার

@ সুজাসনেয়ার এই ফাইলটির নাম না থাকার কারণ, এবং নামটি লেখার __repr__পদ্ধতি File। আপনি যদি পছন্দ করেন তবে আপনি এটিটি তৈরির পরে এটিতে nameএটিবিট সেট করতে পারতেন , তবে আমার অভিজ্ঞতায় এটি কিছু যায় আসে না (আপনি এটি প্রিন্ট করে নিলে এটিকে আরও সুন্দর দেখাবে)। ymmv। FileFile(io)
jbg

3

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

import urllib.request
from django.core.files.uploadedfile import SimpleUploadedFile
from urllib.parse import urlparse

from demoapp import models


img_url = 'https://upload.wikimedia.org/wikipedia/commons/f/f7/Stack_Overflow_logo.png'
basename = urlparse(img_url).path.split('/')[-1]
tmpfile, _ = urllib.request.urlretrieve(img_url)

new_image = models.ModelWithImageOrFileField()
new_image.title = 'Foo bar'
new_image.file = SimpleUploadedFile(basename, open(tmpfile, "rb").read())
new_image.save()

এটি আমার জন্য একমাত্র সমাধান যা কাজ করেছিল (পাইথন 3 + জাজানো 2)। কেবলমাত্র কিছুটা তুচ্ছ মন্তব্যটি হ'ল ইউএসএল উপর নির্ভর করে প্রতিটি ক্ষেত্রে বেসনেমের সঠিক বর্ধন নাও থাকতে পারে।
পদার্থবিজ্ঞান এআই

2

সবেমাত্র আবিষ্কার হয়েছে যে আপনাকে একটি অস্থায়ী ফাইল তৈরি করতে হবে না:

সরাসরি জাজানো থেকে মিনিওতে ইউআরএল বিষয়বস্তু স্ট্রিম করুন

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


-5

এটি সঠিক এবং কার্যকরী উপায়

class Product(models.Model):
    upload_path = 'media/product'
    image = models.ImageField(upload_to=upload_path, null=True, blank=True)
    image_url = models.URLField(null=True, blank=True)

    def save(self, *args, **kwargs):
        if self.image_url:
            import urllib, os
            from urlparse import urlparse
            filename = urlparse(self.image_url).path.split('/')[-1]
            urllib.urlretrieve(self.image_url, os.path.join(file_save_dir, filename))
            self.image = os.path.join(upload_path, filename)
            self.image_url = ''
            super(Product, self).save()

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