Django show ImageField - python

I have extended the base User from Django with the OneToOne method.
class Employee(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
floor = models.CharField(max_length = 100)
avatar = models.ImageField(upload_to='userimages')
The image is uploaded to media/userimages.
Now, when I try to show the avatar, I am trying this way, but it doesn't show anything.
<img src="media/{{ user.employee.avatar.url }}" alt="">
If I just output user.employee.avatar.url, I get:
'media/userimages/name.jpg'
The image exists in that folder, but it doesn't appear on the website.
I really can't figure out why it doesn't work. Any help is appreciated.

You should not use
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
to do this. This is okay only for debug purposes. Otherwise, it's your nginx/apache/other_server that should be responsible for serving static files and media files along with routing the .sock file generated by gunicorn/uwsgi.

I finally figured out how to make it work, so just in case somebody else has the same problem I am going to answer to my question. Basically just add this to settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'app/media')
And this to urls.py:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Related

Django imagefield isn't showing any photo in the template

I'm working on a bookstore using Django. I'm trying to save each book's cover in each book created by the user using imagefield. I implemented every step in Django documentation about using imagefield but it doesn't work.
settings.py(in main project):
MEDIA_DIR = os.path.join(BASE_DIR,'media')
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'
in urls.py (main project):
from django.contrib import admin
from django.urls import include, path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("book.urls")),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
in models.py(the book app):
class books(models.Model):
cover = models.ImageField(upload_to='cover/co', blank=True)
When I want go admin I find that the photo is submitted (when I click on the photo url in database nothing is shown to me) but I don't find any created media folders and when I try to request the image in any template It isn't showed to me.
when I try to click on the photo in the database in admin this is shown to me:
enter image description here
These are the paths of the app, project and static:
enter image description here
I don't know where is the problem and how to solve it as this is my first time to use imagefiled in django model,,, it might be from the paths, the model or the urls so if there is any help.
Remove / at the beginning of your MEDIA_URL.
Simply you can try this way:
settings.py file:
MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR,'media')
In models.py file:
class books(models.Model):
cover = models.ImageField(upload_to='cover/', blank=True) #I have removed co from here
After adding above code don't forget to migrate
Try this and see if this is solves your problem

Populating Django SQL Database

I would like create a database for my images that I could access using django. For the model I want to create something along these lines of
class Images(models.Model):
Image_loc = models.CharField(max_length = 200)
Image_year = models.CharField(max_length = 200)
Image_date = models.DateTimeField('date taken')
Where image_loc is the image file location and image_year is the year that the image was taken. I would like to populate the database with multiple images. I am new to website design and django and was wondering if anyone knew how would I go about doing this?
For images, you should use ImageField. You'll need to install a library named Pillow for it to work (as per the Django docs I just linked). To do that, just run:
python -m pip install Pillow
You'll also need to set up your MEDIA_ROOT and MEDIA_URL (more on that here). All you need to do is append this to your projects settings.py:
# Media files
# https://docs.djangoproject.com/en/dev/topics/files/
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media/")
MEDIA_URL is the url path of the images.
MEDIA_ROOT is the location of the image files.
Then, add this to your PROJECT'S (not app's) urls.py:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
...
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
If you set it up this way, you won't need the image_loc field, since that's automatically managed by ImageField. You can just replace that field with the new ImageField.

Django Media Files (Images) Security

I am working on image handling in Django. I am using normal image model storing method.
So, my model is something like,
class PictureModel(models.Model):
def user_directory_path(instance, filename):
return 'images/{0}/{1}'.format(instance.user.username, filename)
user = models.ForeignKey(User, on_delete=models.CASCADE)
image = models.ImageField(upload_to=user_directory_path)
The view.py is somewhat like,
#login_required(login_url='/accounts/login/')
def myMethod(request):
user = request.user
myImage = PictureModel.objects.get(user=request.user)
return render(request, 'main/myPage.html', {'myImage': myImage})
I have a media root setup as,
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
The url.py setup is as follows,
url(r'^static/(?P<path>.*)$', django.views.static.serve, {'document_root': settings.STATIC_ROOT, 'show_indexes': settings.DEBUG})
Now in normal flow, the image uploading and fetching are working as expected. But the issue is regarding the user validation/authentication while fetching the media file.
Suppose, I am getting an image by the URL,
media/images/user_1/mypic.jpg
But the whole media folder gets exposed without any validations and I can access,
media/images/user_2/mypic.jpg
also through the browser. I have searched on this over the net and found there are some random third party libraries are available but they are not so standard/popular. Can anyone suggest the best practices and libraries to handle the situation.
Add this in your template
it solves the problem
<img style="height:200px; width:200px; border-radius:50%; margin:auto" src="{{ appname.function_name.image.url }}" alt="Photo">

Edit list of pictures that has foreign key to model

I have the following two models:
class Profile(AbstractUser, CommonInfo):
...
pictures = models.ManyToManyField(Picture, blank=True)
and
class Picture(CommonInfo):
picture = models.ImageField(upload_to='gallery/', blank=True, null=True)
What is the best way to display those pictures in a custom template/form/view.
I want to display them all and to delete several of them and add new.
Set media url and root in settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Make changes in urls.py of the project
urlpatterns = [
url(...)
url(...)
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Now you will be able to access the media files in template and perform different operations.

Viewing images uploaded to Django Admin

I have a simple Django admin page that uploads images to a product description. Everything works until I try to view the image by clicking on its path in the products information. I get this error:
Page not found (404)
Request URL: http://0.0.0.0:6666/the_image.jpg
I'm guessing I need to declare something in urls.py, but I have no idea where to start. I also tried changing my media paths in settings.py but I always get errors if I change to anything other than '/'
model.py
class Image(models.Model):
product_image = models.ForeignKey(Product)
image = models.ImageField(upload_to='/')
settings.py
MEDIA_ROOT = '/'
MEDIA_URL = '/'
admin.py
class InlineImage(admin.TabularInline):
model = Image
class ProductAdmin(admin.ModelAdmin):
inlines = [InlineImage]
Docs are here https://docs.djangoproject.com/en/dev/ref/settings/#media-root
You need to set MEDIA_ROOT and MEDIA_URL in your settings file like this
MEDIA_ROOT = /var/www/example.com/media/
MEDIA_URL = /media
and your upload_to should probably be the model name or something to identify it.
image = models.ImageField(upload_to='image')
Then the link should point the /media/image/NAME_OF_IMAGE.png
You will also need to have urls.py setup to server media files. For production you would want to do this in nginx with an alias. See https://docs.djangoproject.com/en/dev/howto/static-files/#serving-files-uploaded-by-a-user-during-development
Which says:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = patterns('',
# ... the rest of your URLconf goes here ...
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Categories

Resources