5

I am new to django and I am confused with the image display problem. Now I have a image of word-cloud generated in the backend(let's say, topicWords.py) and I don't know hot to deal with it. (1) How can I store it in the image field of model UserProfile? In the models.py, I have:

class UserProfile(models.Model):
user = models.OneToOneField(User)
tagcloud = models.ImageField(upload_to ='rap_song/raptle/pic/')

Is it right to directly do like:

user.userprofile.tagcloud = wc #wc is the image generated

(2) What should the setting of MEDIA_ROOT and MEDIA_URL be?

(3) How should I display it in the .html?

<img src = "???">

Thank you very much!

codelover123
  • 187
  • 2
  • 14

3 Answers3

0

MEDIA_URL should be like this:

MEDIA_ROOT='(the full path to the media folder)' (i.e: '/home/jason/work/project/media/')
MEDIA_URL='/media/'

And add these lines to the end of your urls.py file:

urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

You can access it in the templates using:

<img src = "{{ user.userprofile.tagcloud.url }}">

If you want to set an ImageField path in Django manually then you can save the image file and then set the path value when saving the model instance. You can refer this link for more info on it.

JRodDynamite
  • 12,325
  • 5
  • 43
  • 63
  • Thank you for your reply! So in my models.py I shouldn't upload the image to the previous address? Should I set it as the same with the MEDIA_ROOT? – codelover123 Nov 22 '15 at 16:44
  • @yobichi - if `upload_to="foo"`, then the photo would go into the "foo" subdirectory of `MEDIA_ROOT`. – JRodDynamite Nov 22 '15 at 16:48
  • Got it! So finally the code user.userprofile.tagcloud.url can choose the right one of the certain user even all the images are in the sam directory? (I want to vote for you but seems I can't ....) – codelover123 Nov 22 '15 at 16:53
  • @yobichi - Yes, the complete path and the image file name will be stored in the database. Django will fetch the required image. – JRodDynamite Nov 22 '15 at 16:56
  • @yobichi - If you are going to store the images manually (using your script) then make sure the file names are unique for each user. That's it! – JRodDynamite Nov 22 '15 at 16:57
  • @yobichi - You can give it a green tick, if this answer has helped you. :) – JRodDynamite Nov 22 '15 at 16:58
  • Hi! Sorry for disturb you again. Now I get the error of ImproperlyConfigured: Empty static prefix not permitted. It is said that the error occurs on this line of code: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) Do you have any ideas? – codelover123 Nov 23 '15 at 06:23
  • @yobichi - This might help, have a look at this [answer](http://stackoverflow.com/a/27131377/2932244). And check the documentation [here](https://docs.djangoproject.com/en/1.8/howto/static-files/). – JRodDynamite Nov 23 '15 at 06:31
  • Thank you Jason! It seems to work! But there is another error: 'WordCloud' object has no attribute '_committed'. What should I do if I want to store the image object to the model of UserProfile, given the wc is the generated image? – codelover123 Nov 23 '15 at 07:29
  • @yobichi - Please read the answer again. Save the image in the system using the WordCloud library (I'm not familiar with it but it should be something like this `wc.to_file("alice.png")`). And then set the path of the file like this `example.image = 'somewhere/special/filename.jpeg'`. Look at this [link](https://andrewbrookins.com/tech/set-the-path-to-an-imagefield-in-django-manually/). – JRodDynamite Nov 23 '15 at 07:51
  • @yobichi - Make sure you save the image in the correct path. It should be saved in the `upload_to` path. This will help django find it when it has to render the image for the HTML page. – JRodDynamite Nov 23 '15 at 07:53
  • Jason, I am really grateful for you patience and time! But I am quite confused with that. I have written my code in comment below. Could you please check where is wrong? Now the error is No such file or directory: '/rapper/rapper1.png'. Thanks a lot. – codelover123 Nov 23 '15 at 08:19
  • I have solved the problem temporally, but with a very dirty way. I even do not need to save the image to the userprofile model. But anyway, thanks a lot. – codelover123 Nov 23 '15 at 09:07
0

settings.py

MEIDA_URL = '/pic/'
MEDIA_ROOT = os.path.join(REPOSITORY_ROOT, 'pic/')

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(REPOSITORY_ROOT, 'static/')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
'/var/www/static/',
)

urls.py

from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static

urlpatterns = [
......
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += staticfiles_urlpatterns()

models.py

class UserProfile(models.Model):
user = models.OneToOneField(User)
tagcloud = models.ImageField(upload_to ='rapper/')

topicWords.py

d = path.dirname("/rapper/")


wc = WordCloud(background_color="white", max_words=2000, font_path='WeibeiSC-Bold.otf')
# generate word cloud
wc.generate_from_frequencies(word_tag)
# save to the "rapper/", right?
wc.to_file(path.join(d,"rapper1.png"))

userprofile.tagcloud = "rapper/rapper1.png"
userprofile.save()
codelover123
  • 187
  • 2
  • 14
0

Django's models.ImageField has a save() method inherited from FileField, which is usually the one you want to use when generating images on the server. That method takes care of upload_to and also works with other file storage backends.

from io import BytesIO
# Or if you use python 2:
# from StringIO import StringIO as BytesIO 
from PIL import Image
from django.core.files.base import ContentFile

wc = Image()  # Create the image somehow
filename = 'filename.png'  # Make a filename as well

in_memory_file = BytesIO()
wc.save(in_memory_file)
profile_image = ContentFile(in_memory_file.getvalue())
user.userprofile.tagcloud.save(name=filename, content=profile_image, save=False)
user.userprofile.save()

Docs: https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.fields.files.FieldFile.save

FieldFile.save(name, content, save=True)

Takes two required arguments: name which is the name of the file, and content which is an object containing the file’s contents. The optional save argument controls whether or not the model instance is saved after the file associated with this field has been altered. Defaults to True.

Note that the content argument should be an instance of django.core.files.File, not Python’s built-in file object.

Håken Lid
  • 22,318
  • 9
  • 52
  • 67
  • Thank you for your reply! But maybe it should be user.userprofile.tagcloud.save('filename.png', content=wc, True) ? But I still get an error of Cannot force both insert and updating in model saving. Do you have any other ideas? – codelover123 Nov 23 '15 at 09:36
  • You should probably use `save=False` if the model instance hasn't been saved to the database yet. – Håken Lid Nov 23 '15 at 12:05
  • I've added some steps needed for saving a `PIL.Image` object. You can find out more in this answer to a similar question: http://stackoverflow.com/a/4544525/1977847 – Håken Lid Nov 23 '15 at 12:20