django imagefield upload_to does not work at all - django

I've written a simple django app to test ImageField, but I'm running into problem where upload_to just doesn't seem to work. Below is the code:
1 from django.db import models
2
3 # Create your models here.
4 class TestImage(models.Model):
5 img = models.ImageField(max_length=256, upload_to='images')
In my settings.py I have:
2 from os.path import dirname, join, abspath
3 __dir__ = dirname(abspath(__file__))
50 MEDIA_ROOT = join(__dir__, 'static')
55 MEDIA_URL = '/media/'
Then I start python shell using manage.py:
jchin#ubuntu:~/workspace/testimage$ ./manage.py shell
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import settings
>>> from image_app.models import TestImage
>>> p = TestImage(img='test.jpg')
>>> p.save()
>>> p.img.name
'test.jpg'
>>> p.img.path
u'/home/jchin/workspace/testimage/static/test.jpg'
>>> p.img.url
'/media/test.jpg'
As you can see from the result, django totally ignored my 'upload_to' paramater. Which I can't figure out why. From the documentation I should be expecting p.img.path to return "/home/jchin/workspace/testimage/static/images/test.jpg" and in the DB storing "images/test.jpg", correct? But the DB simply store the file name only:
mysql> select * from image_app_testimage;
+----+-----------+
| id | img |
+----+-----------+
| 1 | test.jpg |
+----+-----------+
1 rows in set (0.00 sec)
I checked all the documentations and I could not find what I am doing wrong. Anyone have any ideas? I'm using django 1.2.5 and it should support upload_to.
Please help!
John

But upload_to is for uploading, as the name implies. You're not uploading, you're assigning an image directly. It's only when you create a FileField object - by uploading from a form, for example - that upload_to is used.

Daniel Roseman is correct, upload_to is only used when creating a FileField object.
If you're doing something in a less-traditional manner (in my case, having a separate process place a file into a directory and simply informing Django of it's existence), to use the .url property on a FileField/ImageField, the following may work for you:
import os
from django.core.files.storage import FileSystemStorage
from django.db import models
class Video(models.Model):
video = models.FileField(
upload_to=settings.VIDEO_MEDIA_URL,
storage=FileSystemStorage(
location=settings.VIDEO_FILES_PATH,
base_url=os.path.join(settings.MEDIA_URL, settings.VIDEO_MEDIA_URL)
))
and in settings.py:
MEDIA_URL = '/media/'
VIDEO_MEDIA_URL = 'videos/' # Note: Trailing slash required.
Now, the url property should return the proper path:
>>> from test_app.models import Video
>>> p = Video(video='test.mp4')
>>> p.save()
>>> p.video.name
'test.mp4'
>>> p.video.path
u'/home/alukach/Projects/test/media_dir/videos/test.mp4'
>>> p.video.url
'/media/videos/test.mp4'

FYI, it's important to have enctype="multipart/form-data" part of the form declaration in the HTML template, otherwise the FileField/ImageField might not work appropriately.

This Works for me...
Models.py
img = models.ImageField(upload_to='static/images', default='', blank=True)
Admin.py
class TestImage(admin.ModelAdmin):
fieldsets = [['Some text', {'fields': ['img']}],]
now you can upload your image.

Related

Timezone It works locally but not in pythonanywhere (DJango)

I have a queryset to list today's sales
from django.utils import timezone
class VentaToday(ListView):
queryset = Venta.objects.filter(fecha=timezone.now()).order_by('-id')
template_name = 'venta/venta_today.html'
In local, this works correctly but in production (Pythonanywhere) the sales of the previous day keep appearing. To fix it, I have to go to the pythonanywhere panel and click on the ** reload ** button to solve the problem.
I changed the server time:
Image of server time
Configuration of the django project:
LANGUAGE_CODE = 'es-pe'
TIME_ZONE = 'America/Lima'
USE_I18N = True
USE_L10N = True
USE_TZ = True
Is it a server cache problem? or something am I doing wrong?
UPDATE
config WSGI:
# +++++++++++ DJANGO +++++++++++
# To use your own django app use code like this:
import os
import sys
os.environ["TZ"] = "America/Lima"
#
## assuming your django settings file is at '/home/dnicosventas/mysite/mysite/settings.py'
## and your manage.py is is at '/home/dnicosventas/mysite/manage.py'
path = '/home/dnicosventas/dnicos-ventas'
if path not in sys.path:
sys.path.append(path)
#
os.environ['DJANGO_SETTINGS_MODULE'] = 'DnicosVentas.settings'
#
## then, for django >=1.5:
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
## or, for older django <=1.4
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
and my console:
export TZ="/usr/share/zoneinfo/America/Lima"
Even so, after 12 a.m., yesterday's sales keep appearing until I click on the reload button in the pythonanywhere panel.
Views.py:
class VentaToday(ListView):
today = datetime.now(pytz.timezone('America/Lima'))
queryset = Venta.objects.filter(fecha=today).order_by('-id')
template_name = 'venta/venta_today.html'
Image of the reload button
Solution by Giles Thomas:
class VentaToday(ListView):
template_name = 'venta/venta_today.html'
def get_queryset(self):
return Venta.objects.filter(fecha=datetime.now(pytz.timezone('America/Lima'))).order_by('-id')
TLDR: I had the same issue. I fixed it by changing TIME_ZONE='' to TIME_ZONE='UTC', in the settings.py file in project folder of pythonanywhere.
Python by default uses pytz.timezone(settings.TIME_ZONE), to initiate the time zone of the webapp, and since by default pythonanywhere doesnt initiate this variable, leaving it to the end user to do it, as per their requirements. So initiate your TIME_ZONE, as per your needs, which may do the trick.
You could also try looking in your project log files, for more information on this.

Static and Media Files in Django 1.10

I have a ImageField in my user_accounts/models.py file which i use to store the profile picture of users.It has a upload_to field which calls a function and uploads the file to a media folder in myproj/media/.. . The Image Field also has a default field which is used to set the default profile image from the static folder.
This is an entry of User Table in development server.
In The image the avatar field shows static url but when clicked it /media/ gets attached to the url before /static/ as follows:
In The image the url bar shows /media/ attached before the static url.When i manually remove the /media/ from the url the defaultProfileImage is shown.
This is my project structure
|-myproj
|-myproj
|-__init__.py
|-settings.py
|-urls.py
|-wsgi.py
|-static
|-user_accounts
|-images
|-defaultrofileImage.png
|-user_accounts
|-__init__.py
|-models.py
|-admin.py
|-tests.py
|-views.py
|-urls.py
Models.py File
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import AbstractUser
def get_upload_url(instance , filename):
return 'userProfileImages/%s/%s'%(instance.username , filename)
class User(AbstractUser):
mobileNumber = models.IntegerField(blank = True , null = True)
avatar = models.ImageField(upload_to = get_upload_url , default = '/static/user_accounts/images/defaultProfileImage.png')
def __str__(self):
return self.username
I have the following lines added in my settings.py file
AUTH_USER_MODEL = 'user_accounts.User'
STATIC_URL = '/static/'
STATICFILES_DIRS =[
os.path.join(BASE_DIR,'static'),
]
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
This is my urls.py file
from django.conf.urls import url,include
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls')),
url(r'^user/',include('user_accounts.urls')),
] + static(settings.MEDIA_URL , document_root = settings.MEDIA_ROOT)
How should i correct the url so that when i click the url in my admin panel it shows the correct url in url bar and i get to see the defaultProfileImage??
ImageField default value refers to 'MEDIA_URL', therefore you should create media folder, place your defaultProfileImage there and use default = 'defaultProfileImage.png' in the model field, as in your example it resolves the picture path as MEDIA_URL + default so you get /media/static/....
You probably could omit default= from the model field and override save method to programmatically define the path to the avatar field.
Usually, user-uploaded media files reside in the MEDIA_ROOT and static assets in STATIC_DIRS.
You can find more info here and read about FileField which is the base class of ImageField here.

Why django timesince is not working?

I am trying to use timesince from django but I want it shows "semana" instead of "week", as far as I knew we just need to set 2 things in settings and it should work
>>> from django.conf import settings
>>> settings.USE_I18N
True
>>> settings.LANGUAGE_CODE
'pt-br'
>>> timesince(datetime.now() - timedelta(days=7))
u'1 week'
What is wrong here?
More information: I am on Ubuntu 16 and I have a Mac where the code works
Try the following, see if there is any difference
from django.utils import translation
translation.activate('pt-br')
print timesince(datetime.now() - timedelta(days=7))

How to get the link of the file in a FileField?

how can I get the link of a FileField? I tried the url field, but it gives the file path:
In [7]: myobject.myfilefield.path
Out[7]: u'/home/xxxx/media/files/reference/1342188147.zip'
In [8]: myobject.myfilefield.url
Out[8]: u'/home/xxxx/media/files/reference/1342188147.zip'
I was expecting to get http://<mydomain>/media/files/reference/1342188147.zip
How can I get that? Do I have to build the string manually?
EDIT
My MEDIA_URL was not set, but I still can't get it to work:
settings.py
MEDIA_ROOT = '/home/xxx/media/'
MEDIA_URL = 'http://xxx.com/media/'
models.py
class Archive(models.Model):
#...
file = models.FileField(upload_to="files")
in shell
a = Archive()
a.file = "/some/path/to/file.txt"
a.save()
Then I get for a.path:
"/some/path/to/file.txt"
and for a.url:
"http://xxx.com/media/some/path/to/file.txt"
When done programmatically, a.file = "/some/path/to/file.txt", the file is not uploaded to MEDIA_ROOT. How can I upload a file in the directory defined by upload_to, i.e. in my case /home/xxx/media/file.txt?
The output is based on your settings file, have a look here for an understanding on serving staticfiles in development and/or production:
Confusion in Django admin, static and media files
I'm guessing you have the field defined as:
picture = models.ImageField(upload_to="/home/xxx/media/files/reference")
in other words is it possible you have defined an absolute path for the upload_path property of the field ?
Try something like
from django.conf import settings
picture = models.ImageField(upload_to=settings.MEDIA_ROOT + "files/reference")

wsgi + django returning imports as NoneType

I have an application that works absolutely fine when run as ./manage.py runserver (or even runserver_plus), but when I deploy it to an apache2+wsgi instance, it breaks. The first model it tries to import (UserProfile) it appears to have imported the requested modules as NoneType.
So, a model like this (this is not exact code, it's not something I can paste onto a public site right now):
from django.db import models
from django.contrib.auth.models import User
from BlogEngine.categorisation.models import Category
from django.db.models.signals import post_save
from django.conf import settings
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext as _
import logging
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
category = models.ManyToManyField(Category, blank=True, related_name="category")
def __unicode__(self):
return "Profile for %s" % user.username
def update_categories(self):
"""Updates the categories list"""
pull_more = self.category_selection_max - self.category.count()
if pull_more == 0:
return self.category_selection
logging.debug("Drawing %s categories" % draw)
categories = Category.objects.filter(
is_live=True
).order_by("?")[:pull_more]
## More code under here ##
Returns:
'NoneType' object has no attribute 'debug'
at the line logging.debug("Drawing %s categories" % draw)
Commenting that out results in getting
'NoneType' object has no attribute 'objects'
at the line below it instead, and so on. Everything's definitely being imported, and it works fine under the dev server.
My WSGI file is:
import sys
import site
import os
vepath = '/home/aquarion/newsite/django/virtualenv/lib/python2.6/site-packages'
#prev_sys_path = list(sys.path)
## add the site-packages of our virtualenv as a site dir
site.addsitedir(vepath)
## add the app's directory to the PYTHONPATH
sys.path.append('/home/aquarion/newsite/django/')
# import from down here to pull in possible virtualenv django install
from django.core.handlers.wsgi import WSGIHandler
os.environ['DJANGO_SETTINGS_MODULE'] = 'BlogEngine.settings'
application = WSGIHandler()
Any ideas?
Solved it.
Not sure if it's a bug in something, but it ended up being an issue with using django's user profile stuff and having Admin model information in the models.py file. Once I moved all that into its own admin.py file, everything worked.
Still not sure what causes it exactly, but that's the solution.
(Solution reached via http://osdir.com/ml/DjangoUsers/2009-07/msg00090.html and its reply)