I'm been working on this Photo Organizer and Sharing App Part I at http://lightbird.net/dbe/photo.html. I'm trying to add a picture and when I do . I get this error.
Page not found (404)
Request Method: GET
Request URL: http://donkey123.pythonanywhere.com/admin/photo/image/1/images/Penguins_7.jpg/
image object with primary key u'1/images/Penguins_7.jpg' does not exist.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
My Models is
from django.db import models
from django.contrib.auth.models import User
from django.contrib import admin
from string import join
import os
from PIL import Image as PImage
from mysite.settings import MEDIA_ROOT
class Album(models.Model):
title = models.CharField(max_length=60)
public = models.BooleanField(default=False)
def __unicode__(self):
return self.title
class Tag(models.Model):
tag = models.CharField(max_length=50)
def __unicode__(self):
return self.tag
class Image(models.Model):
title = models.CharField(max_length=60, blank=True, null=True)
image = models.FileField(upload_to="images/")
tags = models.ManyToManyField(Tag, blank=True)
albums = models.ManyToManyField(Album, blank=True)
created = models.DateTimeField(auto_now_add=True)
rating = models.IntegerField(default=50)
width = models.IntegerField(blank=True, null=True)
height = models.IntegerField(blank=True, null=True)
user = models.ForeignKey(User, null=True, blank=True)
def __unicode__(self):
return self.image.name
def save(self, *args, **kwargs):
"""Save image dimensions."""
super(Image, self).save(*args, **kwargs)
im = PImage.open(os.path.join(MEDIA_ROOT, self.image.name))
self.width, self.height = im.size
super(Image, self).save(*args, ** kwargs)
def size(self):
"""Image size."""
return "%s x %s" % (self.width, self.height)
def __unicode__(self):
return self.image.name
def tags_(self):
lst = [x[1] for x in self.tags.values_list()]
return str(join(lst, ', '))
def albums_(self):
lst = [x[1] for x in self.albums.values_list()]
return str(join(lst, ', '))
def thumbnail(self):
return """<img border="0" alt="" src="/media/%s" height="40" />""" % (
(self.image.name, self.image.name))
thumbnail.allow_tags = True
class AlbumAdmin(admin.ModelAdmin):
search_fields = ["title"]
list_display = ["title"]
class TagAdmin(admin.ModelAdmin):
list_display = ["tag"]
class ImageAdmin(admin.ModelAdmin):
search_fields = ["title"]
list_display = ["__unicode__", "title", "user", "rating", "size", "tags_", "albums_","thumbnail","created"]
list_filter = ["tags", "albums","user"]
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()
I think My Models,py is fine but I think the problem lay at the
MEDIA_ROOT= and MEDIA URL=
My MEDIA_ROOT = '/home/donkey123/mysite/photo'
and my MEDIA_URL is "" which is blank.
I don't know what to put for my MEDIA_URL which is the problem.
Thanks in advance
In your model (note there is no need for the slash at the end):
image = models.FileField(upload_to="images")
That means these images will go in {media folder}/images/
In settings.py:
MEDIA_ROOT = os.path.join(os.path.dirname(__file__), '../../web/media').replace('\\','/')
That means the media folder is: project_root/web/media
So the images from this model will go in: project_root/web/media/images
The stuffs above define where the images are saved on the filesystems. Now what you want to do is to define where they will be accessed via HTTP.
In settings.py define the url pointing to the media folder:
MEDIA_URL = '/media/'
Then the images from this model will be in:
http://my-url/media/images/image_name.jpg
Tests these settings without your model/library first with one image. Then read the following:
To reply to your specific questions:
My MEDIA_ROOT = '/home/donkey123/mystic/photo' => see my example, the MEDIA_ROOT should be relative to your settings.py file so it will work when going live, on another dev machine, etc.
and my MEDIA_URL= is "" which is blank. => that should be '/media/' because in the model you are doing this:
def thumbnail(self):
return """<a href="/media/%s">
Hope that helps
settings.py
import os
PROJECT_ROOT = os.path.join(os.path.dirname(__file__), '..')
SITE_ROOT = PROJECT_ROOT
MEDIA_ROOT = os.path.join(SITE_ROOT, 'media')
MEDIA_URL = '/media/'
Problem is with the regular expression in your urls.py, which is taking everything after 1 and passing it in as the primary key.
I think, When any web page is removed or moved then 404 happens. Otherwise your hosting provider is not good.
Related
This is my model:
def group_based_upload_to(instance, filename):
return "media/image/lavorazione/{}".format(instance.prestazione.id,)
class ImmaginiLavorazioni(models.Model):
immagine = models.ImageField(upload_to=group_based_upload_to)
prestazione = models.ForeignKey(Listino, on_delete=models.SET_NULL, null=True,
blank=True, default=None, related_name='Listino3')
and my form:
class ImmagineUploadForm(forms.ModelForm):
class Meta:
model = ImmaginiLavorazioni
exclude = ('preventivo', )
I need a view to save an image in a specific path.
The name of path must be the pk of foreign key.
How can I do that?
I use a model of how a blog post works. You can adjust the example on your needs. You should try and avoid saving the location path from a view.
On your models.py:
# Create your models here.
def upload_location(instance, filename):
filebase, extension = filename.split(".")
return "%s/%s" % (instance.id, filename)
class Post(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to=upload_location,
null=True,
blank=True,
height_field="height_field",
width_field="width_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
content = HTMLField()
formfield_overrides = {
models.TextField: {'widget': AdminPagedownWidget },
}
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
On your forms.py:
from django import forms
from pagedown.widgets import PagedownWidget
from pagedown.widgets import AdminPagedownWidget
from .models import Post
class PostForm(forms.ModelForm):
content = forms.CharField(widget=PagedownWidget(show_preview=False))
class Meta:
model = Post
fields = [
"title",
"content",
"image"
]
class PostModelForm(forms.ModelForm):
content = forms.CharField(widget=AdminPagedownWidget())
class Meta:
model = Post
fields = '__all__'
And on your settings.py:
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media_cdn")
Here is your view.py:
# Create your views here.
def post_create(request):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
form = PostForm(request.POST or None, request.FILES or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
messages.success(request, "Succefully Created")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
}
return render(request, "post_form.html", context)
The next code has an example without form but you can modify based on your needs.
Below the settings.py
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, '../media')
Firstable, I defined the path of the image in the helpers.py
from django.conf import settings
from datetime import datetime
def upload_to_image_post(self, filename):
"""
Stores the image in a specific path regards to date
and changes the name of the image with for the name of the post
"""
current_date = datetime.now()
return '%s/posts/main/{year}/{month}/{day}/%s'.format(
year=current_date.strftime('%Y'), month=current_date.strftime('%m'),
day=current_date.strftime('%d')) % (settings.MEDIA_ROOT, filename)
You could define the image's name with some code like this one. But you have to regard you should have the pk to replace the name of the image
ext = filename.split('.')[-1]
name = self.pk
filename = '%s.%s' % (name, ext)
So, I called the def in my models.py, specifically in the image's field
from django.db import models
from django.utils.text import slugify
from .helpers import upload_to_image_post
class Post(models.Model):
"""
Store a simple Post entry.
"""
title = models.CharField('Title', max_length=200, help_text='Title of the post')
body = models.TextField('Body', help_text='Enter the description of the post')
slug = models.SlugField('Slug', max_length=200, db_index=True, unique=True, help_text='Title in format of URL')
image_post = models.ImageField('Image', max_length=80, blank=True, upload_to=upload_to_image_post, help_text='Main image of the post')
class Meta:
verbose_name = 'Post'
verbose_name_plural = 'Posts'
I hope this helped you
Now this is my models:
def group_based_upload_to(instance, immagine):
return "media/preventivo/{pk}/{image}".format(pk=instance.preventivo.id, image=immagine)
class ImmaginiLavorazioni(models.Model):
immagine = models.ImageField(upload_to=group_based_upload_to)
preventivo = models.ForeignKey(Preventivo, on_delete=models.SET_NULL, null=True, blank=True,
default=None, related_name='Listino3')
And this is my view:
def upload_immagine(request, pk):
member = get_object_or_404(Preventivo, pk=pk)
if request.method == 'POST':
form = ImmagineUploadForm(request.POST or None, request.FILES or None)
if form.is_valid():
newimmagine = form.save(commit=False)
newimmagine.preventivo_id = member.pk
newimmagine.save()
return redirect('preventivo_new2', pk=member.pk)
else:
form = ImmagineUploadForm(request.POST or None, request.FILES or None)
return render(request, 'FBIsystem/upload_immagine.html', {'member': member, 'form': form})
It save in db the file path and the foreign key like:
immagine= media/preventivo/6/image.jpg
preventivo_id = 6
but not create a folder and not save the uploaded image...
I have an Ourteam App that allows you to upload an image, name, title, and social media information for employees. Whenever I create an object the "default.jpg" file is deleted from the media_root.
This is my model:
from django.db import models
from cms.models.pluginmodel import CMSPlugin
from django.utils.translation import ugettext_lazy as _
from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor
from django.template.defaultfilters import slugify
class Employee(CMSPlugin):
# Set Name
name = models.CharField(_('name'), max_length=48)
# Define Slug
slug = models.SlugField(max_length=40, null = False, blank = True)
# Set Title
title = models.CharField(_('title'), max_length=48)
# Set Image upload path and image properties
image_upload_path = 'ourteam/%Y/%m/%d'
image = fields.ImageField(upload_to=image_upload_path,
blank=True, default='ourteam/default.jpg',
dependencies=[
FileDependency(processor=ImageProcessor(
format='JPEG', scale={'max_width': 150, 'max_height': 150}))
])
created = models.DateTimeField(_('created'), auto_now_add=True)
email = models.EmailField(_('email'), max_length=254)
# Social Media
twitter = models.CharField(_('twitter'), max_length=24, blank=True, default='https://www.twitter.com')
linkedin = models.CharField(_('linkedin'), max_length=24,blank=True, default='https://www.linkedin.com')
facebook = models.CharField(_('facebook'), max_length=24,blank=True, default='https://www.facebook.com')
class Meta:
verbose_name = _('employee')
verbose_name_plural = _('employee')
db_table = 'employee'
ordering = ('-created',)
get_latest_by = 'created'
def __unicode__(self):
return u'%s' % self.title
def __str__(self):
return self.name
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Employee, self).save(*args, **kwargs)
def get_all_employees():
all_entries = Employee.objects.all().order_by('created')
return all_entries
def slug(sluggy):
sluggy = sluggy.replace(' ', '-').lower()
return slugify(sluggy)
You should try with that :
def user_directory_path(instance, filename):
# file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
return 'user_{0}/{1}'.format(instance.user.id, filename)
class MyModel(models.Model):
upload = models.FileField(upload_to=user_directory_path)
I have simply model:
class SimplyModel(models.Model):
name = models.CharField(max_length=50)
image = models.ImageField(upload_to="images/", blank=True, null=True)
def get_image(self):
return self.image.path
def __str__(self):
return self.name
And I serilize it by
from django.core import serializers
def get_my_model(request):
#some operations...
data = serializers.serialize('json', SimplyModel.objects.all())
return HttpResponse(
data,
content_type="application/json"
)
But on frontend when I service this data, in image filed I have only:
images/myimage.jpg
without media prefix.
I have all 'media-configuration'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "../media")
And I can get this image by serveradress.com/media/images/myimage.jpg
I tried to add method to model, like
def get_image(self):
return self.image.path
But I cannot see this method in my respons.
How can I get this absolute path? Or serilize method by django-core serialzer? (I don't want to use DRF)
Best
You do not need to add a method to your model to get the url.
Just access it in your template by using the built in .url method.
Example of how it works:
obj = SimplyModel.objects.get(pk=123)
url = obj.image.url
I have defined a model with a 'pic' image field:
class Photo(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
teaser = models.TextField('teaser', blank=True)
pic = models.ImageField(upload_to = 'pic_folder/', default = 'pic_folder/None/default.jpg')
created=models.DateTimeField(default=datetime.datetime.now)
pub_date=models.DateTimeField(default=datetime.datetime.now)
categories = models.ManyToManyField(Category, blank=True)
likes = models.IntegerField(default=0)
dislikes = models.IntegerField(default=0)
visits = models.IntegerField(default=0)
slug = models.CharField(max_length=100, unique=True, blank=True)
And here is the upload form:
class PhotoForm(forms.ModelForm):
class Meta:
model= Photo
fields = ( 'title', 'pic','body', 'categories')
Wich post to this view:
#staff_member_required
def add_photo(request):
if request.method == 'POST':
form = PhotoForm(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.info(request, "photo was added")
return render(request, 'home.html')
else:
messages.info(request, 'form not valid')
return render(request, 'home.html')
if request.method == 'GET':
form = PhotoForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render(request, 'photo/add_photo.html', args)
The problem is that while photo objects are being saved and the file uploaded but the images are not displayed.
<div class="photo_body"><img src="pic_folder/someimage.jpg" ></div>
I also set
MEDIA_ROOT = '/path/to/my_project/pic_folder'
and run manage.py collectstatic, but they did not solve the problem.
I really got confused about this. So appreciate your hints.
First of all make a folder called media in your project's directory.
Django will store all your uploaded images inside media/pic_folder/ automatically.
In your settings.py file, add this:
MEDIA_URL = '/media/'
MEDIA_ROOT = '/path_to/media/' # write the path to the media folder you just created.
In your urls.py file, add the following lines at the top:
from django.conf import settings
from django.conf.urls.static import static
and add the following line at the end:
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
something like below:
urlpatterns = patterns('',
# Your urls here
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
And, finally, in your templates:
<img src="{{MEDIA_URL}}pic_folder/someimage.jpg" />
I'm been working on this Photo Organizer and Sharing App Part I at http://lightbird.net/dbe/photo.html. I'm trying to generate a thumbnail and when I do . I get this error.
I have Windows Vista.
IOError at /admin/photo/image/add/
(13, 'Permission denied')
Request Method: POST
Request URL: http://127.0.0.1:8000/admin/photo/image/add/
Django Version: 1.4.3
Exception Type: IOError
Exception Value: (13, 'Permission denied')
Exception Location:C:\Python26\lib\site-packages\PIL\Image.py in save, line 1399
Python Executable:C:\Python26\python.exe
Python Version: 2.6.0
Python Path:
['C:\\djcode\\mysite',
'C:\\Python26\\python26.zip',
'C:\\Python26\\DLLs',
'C:\\Python26\\lib',
'C:\\Python26\\lib\\plat-win',
'C:\\Python26\\lib\\lib-tk',
'C:\\Python26',
'C:\\Python26\\lib\\site-packages',
'C:\\Python26\\lib\\site-packages\\PIL']
Server time: Sun, 10 Feb 2013 23:49:34 +1100
My models.py is
from django.db import models
from django.contrib.auth.models import User
from django.contrib import admin
from string import join
from django.core.files import File
from os.path import join as pjoin
from tempfile import *
import os
from PIL import Image as PImage
from mysite.settings import MEDIA_ROOT
class Album(models.Model):
title = models.CharField(max_length=60)
public = models.BooleanField(default=False)
def __unicode__(self):
return self.title
class Tag(models.Model):
tag = models.CharField(max_length=50)
def __unicode__(self):
return self.tag
class Image(models.Model):
title = models.CharField(max_length=60, blank=True, null=True)
image = models.FileField(upload_to="images/")
tags = models.ManyToManyField(Tag, blank=True)
albums = models.ManyToManyField(Album, blank=True)
created = models.DateTimeField(auto_now_add=True)
rating = models.IntegerField(default=50)
width = models.IntegerField(blank=True, null=True)
height = models.IntegerField(blank=True, null=True)
user = models.ForeignKey(User, null=True, blank=True)
thumbnail2 = models.ImageField(upload_to="images/", blank=True, null=True)
def __unicode__(self):
return self.image.name
def save(self, *args, **kwargs):
"""Save image dimensions."""
super(Image, self).save(*args, **kwargs)
im = PImage.open(pjoin(MEDIA_ROOT, self.image.name))
self.width, self.height = im.size
# large thumbnail
fn, ext = os.path.splitext(self.image.name)
im.thumbnail((128,128), PImage.ANTIALIAS)
thumb_fn = fn + "-thumb2" + ext
tf2 = NamedTemporaryFile()
im.save(tf2.name, "JPEG")
self.thumbnail2.save(thumb_fn, File(open(tf2.name)), save=False)
tf2.close()
# small thumbnail
im.thumbnail((40,40), PImage.ANTIALIAS)
thumb_fn = fn + "-thumb" + ext
tf = NamedTemporaryFile()
im.save(tf.name, "JPEG")
self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)
tf.close()
super(Image, self).save(*args, ** kwargs)
def size(self):
"""Image size."""
return "%s x %s" % (self.width, self.height)
def __unicode__(self):
return self.image.name
def tags_(self):
lst = [x[1] for x in self.tags.values_list()]
return str(join(lst, ', '))
def albums_(self):
lst = [x[1] for x in self.albums.values_list()]
return str(join(lst, ', '))
def thumbnail(self):
return """<img border="0" alt="" src="/media/%s" height="40" />""" % (
(self.image.name, self.image.name))
thumbnail.allow_tags = True
class AlbumAdmin(admin.ModelAdmin):
search_fields = ["title"]
list_display = ["title"]
class TagAdmin(admin.ModelAdmin):
list_display = ["tag"]
class ImageAdmin(admin.ModelAdmin):
search_fields = ["title"]
list_display = ["__unicode__", "title", "user", "rating", "size", "tags_", "albums_","thumbnail", "created"]
list_filter = ["tags", "albums"]
def save_model(self, request, obj, form, change):
obj.user = request.user
obj.save()
The problem is here:
from django.core.files import File
from os.path import join as pjoin
from tempfile import *
class Image(models.Model):
# ...
thumbnail2 = models.ImageField(upload_to="images/", blank=True, null=True)
def save(self, *args, **kwargs):
"""Save image dimensions."""
super(Image, self).save(*args, **kwargs)
im = PImage.open(pjoin(MEDIA_ROOT, self.image.name))
self.width, self.height = im.size
# large thumbnail
fn, ext = os.path.splitext(self.image.name)
im.thumbnail((128,128), PImage.ANTIALIAS)
thumb_fn = fn + "-thumb2" + ext
tf2 = NamedTemporaryFile()
im.save(tf2.name, "JPEG")
self.thumbnail2.save(thumb_fn, File(open(tf2.name)), save=False)
tf2.close()
# small thumbnail
im.thumbnail((40,40), PImage.ANTIALIAS)
thumb_fn = fn + "-thumb" + ext
tf = NamedTemporaryFile()
im.save(tf.name, "JPEG")
self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)
tf.close()
super(Image, self).save(*args, ** kwargs)
How do I fix this error?
It looks to me like django doesn't have the permissions it needs to access your MEDIA_ROOT folder.
Have a look at your MEDIA_ROOT settings in your settings.py file. Then check the permissions on the folder (something like ls -lsa /path/to/media_root from a bash shell). Make sure the user running django as write permission to the folder.
Also, as asermax points out, make sure you have created an images directory within your MEDIA_ROOT.
Have a look at the documentation for serving static files particularly the section on serving other directories
UPDATE
Perhaps it's this issue. Try replacing im.save(tf2.name, "JPEG") with im.save(tf2, "JPEG")
set SELinux permisions
http://wiki.apache.org/httpd/13PermissionDenied
take a look to this, it may be there the solution