have the following problem, I have in my settings.py configured in the following way:
RUTA_PROYECTO = os.path.dirname(os.path.realpath(__file__))
MEDIA_ROOT = os.path.join(RUTA_PROYECTO,'fotos')
MEDIA_URL = '/media/'
In my urls file I have:
from django.conf.urls.static import static
Urlpatterns = patterns ('',
....
) + static (settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
I have in my models
def upload_name(instance, filename):
return '{}/{}'.format(instance.persona.nro_doc, filename)
class FotosPersona(models.Model):
persona = models.ForeignKey(Personas,related_name='fotos_persona')
tipo_foto = models.CharField(max_length=25)
foto = models.ImageField(upload_to=upload_name)
fecha = models.DateField(auto_now=True)
class Meta:
db_table = 'fotos_persona'
When I save the data, the image is stored in a folder within the following structure:
Project
|
|
|----Project
|---- settings.py
|---- media
|---- urls.py
.....
But when I want to display the image in a template, it is not displayed.
When in the browser I entered the
http://localhost:8000/media/other_folder/image_file.jpg url
it returns me an HTTP 500 error.
I know my answer is a little late, but this might be useful considering your set up. Essentially, you have given the MEDIA_URL as "/media/". This is all right.
However, you would be facing a problem with reference to the URL patterns. You will probably have a generic URL along the lines of:
path('<index>', views.index, name='index'),
In such a scenario this URL would be processing everything that comes from the media URL. Although this is not ideal, only for the purpose of development I would recommend changing your URL patterns to the following:
urlpatterns = static (settings.MEDIA_URL, document_root = settings.MEDIA_ROOT) + [
...
]
Now in the hierarchy of processing URL patterns "/media/" would come before any URL that has a general pattern. Now media URLs would be processed before everything else.
Hopefully, this can address your query.
Related
I have seen many questions here regarding media files in Django, but honestly I can't find a valid solution for my problem.
So I have decided to streamline the environment to a very simple application.
You can find it here: github project
I have created a project with django-admin and I called 'documents' and then I have created an app called 'docs'.
Then I defined a simple class:
def get_path(instance, filename):
fn, ext = os.path.splitext(filename)
ts = str(int(time.time()))
return os.path.join('{}_{}{}'.format(fn, ts, ext))
class doc(models.Model):
doc_name = models.CharField(max_length=30, verbose_name=u"doc name", help_text=u"name of the doc")
doc_document = models.FileField(upload_to=get_path, verbose_name=u"document", help_text=u"document")
class Meta:
unique_together = ("doc_name", )
def __str__(self):
return f"{self.doc_name}"
This changes the filename and it adds a timestamp.
I also changed the urls.py file adding the following:
path(r'', admin.site.urls),
Now the question is: without using MEDIA_URL and MEDIA_ROOT is it possible to make this working?
I have tried to add a files and it works:
and it properly save the file in the root of the project.
But when I go to the link and click I am getting the following:
Now is it possible to know where is it looking for the file?
Do you think that adding MEDIA_URL and MEDIA_ROOT would help? How should I add it?
I have already tried but without any success.
Additional information
If I set my project in urls.py:
Then I am getting this:
Following the tutorial: https://www.sitepoint.com/django-photo-sharing-app/
I basically changed 3 things:
1-created docs/urls.py and put:
urlpatterns = []
2-changed documents/urls.py to:
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include
from django.contrib import admin
urlpatterns = [
path('admin/', admin.site.urls),
# Main app
path('', include('docs.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
3-in documents/settings.py just put the following:
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media/'
it works.
I'm trying to accomplish something I believed would be simple: upload an image (via admin), then use the complete URL in a template to display the image.
The problem is I can only print the relative URL: /pics/filename.jpg. I believe the sequence is settings.py (MEDIA_ROOT, MEDIA_URL), urls.py, views.py and then mytemplate.html.I hope someone can find what's missing.
Settings:
STATIC_URL = '/static/'
MEDIA_ROOT = '/Users/ed/code/projects/djcms/pics/'
MEDIA_URL = '/pics/'
Urls.py:
from django.conf import settings
from django.conf.urls.static import url, static
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^news/(?P<pk>[0-9]+)/$', views.detail, name='detail'),
] + static(r'^$/pics/', document_root = settings.MEDIA_URL)
Views.py
def detail(request, pk):
story = Article.objects.get(pk=pk)
my_pic = Photo.objects.get(pk=pk)
print(story.image.url)
print(my_pic)
print(story.body)
print(request)
context = {'story': story}
return render(request, 'articles/detail.html', context)
The Error with story.image.url:
AttributeError: 'Photo' object has no attribute 'url'
When I remove the .url, I get this partial URL:
pics/intro-bg.jpg
What am I missing? Thanks.
This setup is working for me, maybe it will help you. It is for latest version of Django. Many answers in OS are for older Django versions.
URLS:
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
#url
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Settings:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
Template:
<img src="{{ foo.image.url }}"><br>
Model:
image = models.ImageField(upload_to = 'img/', default = 'img/None/no-img.jpg')
My foo model has an imagefield, when it is stored, I can retrieve the full url through item.image.url based on the above setup.
In urls.py, try: static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The URLS seem to be causing the problem.
from django.conf import settings
from django.conf.urls.static import url, static
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^news/(?P<pk>[0-9]+)/$', views.detail, name='detail'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The logic behind those URL patterns displays my homepage and individual news articles. Each news article has a url of /news/, followed by the article number, i.e. /news/1.
Each article uses my Photo model via a ForeignKey in the Article model. This allows a photo to be tied to a specific article.
However, in my template, the URL is a jumble of news and images:
http://localhost:8000/news/2/img/phones.png.
The news URL correctly finds the news item but not the image associated with the news item. The correct result would display the individual article along with its associated image. Do I need another URL?
The Request object in Django has a method, build_absolute_uri() Using this method you can get absolute url of the image field.
So to get the absolute url, you can use two methods
First method: Getting absolute url in view while doing GET request.
from settings import MEDIA_URL
class ClassName(APIView):
def get(self, *args, **kwargs):
model = models.ModelName.objects.get(name='pran')
absolute_url = self.request.build_absolute_uri('/').strip("/") + MEDIA_URL + str(model.image_field_name)
return Response({'url': absolute_url}, 200)
Method 2: If you are doing POST request and you are using serializer then pass request as context object to it.
ser = serializers.MySerializerName(data=request.data}, context={'request': request})
I can upload an image through the admin page, but the image can not be found when I navigate to the url that is generated by django. (404 error)
The files are being uploaded to the folder:
project_root/media/eventbanner/1/
I have tried multiple solutions but none seem to work for my situation.
Django 1.10 is being run local on Ubuntu 16.04.
The url I get is:
http://localhost:8000/media/eventbanner/1/banner_image.jpg
Media root folder is located at:
/home/username/xxx/xxx/project_name/media
Code in HTML file:
<div class="banner-image">
<img src="{{ event.eventbanner.banner_image.url }}"/>
</div>
url.py code:
from django.conf.urls import url, include
from django.contrib import admin
from . import views
from django.conf import settings
from django.conf.urls.static import static
app_name = 'events'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^details/(?P<event_id>[0-9]+)/$', views.details, name='details'),
url(r'^details/(?P<event_id>[0-9]+)/addcomment/$', views.add_comment, name='add_comment'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS =[os.path.join(BASE_DIR, 'static'),]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
models.py
def validate_only_one_instance(obj):
model = obj.__class__
if (model.objects.count() > 0 and obj.id != model.objects.get().id):
raise ValidationError("Can only create 1 %s instance" % model.__name__)
class EventBanner(models.Model):
event = models.OneToOneField(Event, unique=True)
banner_image = models.ImageField(upload_to=get_image_path, blank=True, null=True)
def clean(self):
validate_only_one_instance(self)
The real problem here is that there is no relationship between this url http://localhost:8000/media/eventbanner/1/banner_image.jpg and this location on disk /home/username/xxx/xxx/project_name/media.
In a production application you'd have a web server where you'd store your Media content, the serving URL would be MEDIA_ROOT and you'd append ImageField.url to this value to get a valid image path.
What you need here is to set up a web server for your media images. At first that sounds like a lot of work, but Django provides a shortcut...
Serving Files in Development
You have some work you need to do to have the media files served locally. It requires some changes to your urls.py ...
from django.conf import settings
from django.views.static import serve
# ... the rest of your URLconf goes here ...
if settings.DEBUG:
urlpatterns += [
url(r'^media/(?P<path>.*)$', serve, {
'document_root': settings.MEDIA_ROOT,
}),
]
This uses the views.serve bit and should only be used in DEBUG mode. It overrides the path to media files(django's term for user uploaded content like ImageField). This will redirect those requests through the serve view. Best I can tell this is a mini web server that will map those request routes to locations on disk and allow those locations to be reachable via HTTP urls.
As of at least Django 1.8, there is a helper function static() that will set this up for you and ensure that it only functions in debug mode.
Your urls.py should look something like this:
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
...to simply quote the documentation.
Make sure that your MEDIA_URL is set to a relative path like /media/ and that your MEDIA_ROOT is an absolute filesystem path like /home/foo/project/media.
I have created a django rest model which includes a FileField.
media = models.FileField(upload_to='media/%Y/%m/%d/', null=True, blank=True)
I also implemented serializer and ListCreateApiView. There I can able to upload a file. On POST request rest server uploads the file in folder and returns me the url. However, on get request, server return json content with the url. If I use the url for get request, server respond Page Not Found. How to download the uploaded file using django rest? Do I have to create separate view for the same? If so, how to do that?
Edit:
The resulting url is
http://localhost:8000/message/media/2015/12/06/aa_35EXQ7H.svg
You have to define MEDIA_ROOT, MEDIA_URL and register MEDIA_URL in urlpatterns to allow Django server to serve these files.
Follow these steps:
settings.py file:
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media_root")
Append this in your main urls.py file to serve media files :
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Also, you don't have to add media again in upload_to attribute because it's prepended by MEDIA_URL, then the url will be /media/media/.
Here is a correct example:
media = models.FileField(upload_to='message/%Y/%m/%d/', null=True, blank=True)
and the url of the media will be:
http://localhost:8000/media/message/2015/12/06/aa_35EXQ7H.svg
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)