Here's my folder structure (all blacked out is just name of project, just assume 'myproject'):
I want to set my home page, ie http://mydomain.com/, as a template HTML. So following this SO post, I set this as my url.py in my myproject project folder:
from django.conf.urls import patterns, include, url
from django.views.generic import TemplateView
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', TemplateView.as_view(template_name="index.html")),
url(r'^events/', include('events.urls', namespace='events')),
url(r'^admin/', include(admin.site.urls)),
)
But Django keeps trying to append this path to the events folder. The DEBUG = True output from the browser indicates that it cannot find this template at
/home/ubuntu/django/myproject/events/templates/templates/myproject/index.html
which of course is not what I was trying to point to. How do I fix this?
Django will try to find index.html template at various folders that you have specified in TEMPLATE_DIRS settings and in templates folder in each app if TEMPLATE_LOADERS setting have 'django.template.loaders.app_directories.Loader'
More details information at Loading Templates
The simplest solution is to make single templates directory on the same level as your apps.
For example:
/home/ubuntu/django/myproject/templates/events
/home/ubuntu/django/myproject/templates/some_other_app
Also, check TEMPLATE_DIRS in your settings file, here is working example:
from os.path import abspath, basename, dirname, join, normpath
DJANGO_ROOT = dirname(dirname(abspath(__file__)))
SITE_ROOT = dirname(DJANGO_ROOT)
TEMPLATE_DIRS = (
normpath(join(SITE_ROOT, 'templates')),
)
You need to define the TEMPLATE_DIRS and try to use absolute paths like this:
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
...
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'templates'),
)
...
If you have some application and your template's folder located as another folder, then you can define the TEMPLATE_DIRS in this manner:
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
...
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'events', 'templates'),
os.path.join(PROJECT_PATH, 'templates'),
)
...
And don't forget to change your views to render the template, something like this:
...
return render_to_response('events/index.html',{},context_instance=RequestContext(request))
...
EDIT:
And change your project's urls something like this:
from events import urls
...
urlpatterns = patterns('',
...
url(r'^events/', include('events.urls', namespace='events')),
...
)
Related
I have a project running in Django 3.1, and suddenly it has started to fail serving media files (static files uploaded by users), even though I haven't changed anything in settings.py or elsewhere.
My main urls.py:
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('cart/', include('cart.urls', namespace='cart')),
path('', include('contacts.urls', namespace='contacts')),
path('customers/', include('customers.urls', namespace='customers')),
path('orders/', include('orders.urls', namespace='orders')),
path('account/', include('account.urls')),
path('', include('catalog.urls', namespace='catalog')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
From my settings.py:
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath( os.path.join(__file__, os.pardir))))
DEBUG = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATIC_URL = '/static/'
STATICFILES_DIRS = ( os.path.join('static'), )
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
I don't know and can't figure out where the mistake is, but runserver just keeps throwing 404 when trying to load media files, even though static files (CSS/JS) are being served correctly.
your Urls looks fine, although i notes that you missing from django.contrib import admin.
About your settings, here is mine that works just fine for me.
Add import os to your settings.py if it is not there.
My code generates Pandas dataframes. They are big. I save them as files. For this, I have created this Model:
models.py:
class TargetFiles(models.Model):
owner = models.CharField(max_length=25)
csv_file = models.FileField(blank=True, upload_to='target')
file_name = models.CharField(max_length=255)
settings.py:
...
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
mycode.py:
file_content = df.to_csv(index=False, encoding='utf-8')
csvname = 'target1.csv'
csf = ContentFile(file_content, csvname)
TargetFiles.objects.create(owner=self.user, csv_file=csf, file_name=csvname)
urls.py (project):
from django.urls import include, path
from django.contrib import admin
urlpatterns = [
path('dataapp/', include('dataapp.urls')),
]
urls.py (dataapp):
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='dataapp'),
path('welcome/', views.welcome_dataapp, name='welcome_dataapp'),
path('download/<str:file_name>', views.download, name='download'),
]
I don't know if this is the best approach for the problem. This documentation made me skeptical. The thing is that my code is generating the file properly, and saving it in the MEDIA_ROOT directory. But when I go to admin view and click on TargetFiles object, the link to the file returns this error:
The current path, media/target/target1.csv, didn't match any of these.
Since I am not an Django expert, I think I am setting something wrong. Maybe in settings.py or in urls.py (in this file I didn't write any reference to media, maybe this is where the error lives).
I have already read these posts:
Django - how to create a file and save it to a model's FileField?
,
Django: generate a CSV file and store it into FileField and this assign resulting csv file to django model. But I was not able to make the admin link point to the MEDIA_ROOT file.
Does anyone have ideas?
Thanks in advance.
Django does not serve the files stored in the MEDIA_ROOT. You can enable this during development by adding the following to your root url config:
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)
https://docs.djangoproject.com/en/3.0/howto/static-files/#serving-files-uploaded-by-a-user-during-development
It's recommended to let file serving be handled by some other server (apache or nginx) whe deploying to a production server.
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.
This is a duplicate of Django Ckeditor image browser not finding images, but I believe the answer there is wrong (there is an obvious bug in it with an undefined variable, not to mention the lack of Python indentation).
I'm using Django CKEditor 5.0.3 and Django 1.9.6. I am able to upload images in my admin, but they appear as a red X within the admin and do not appear on my site.
I'm still struggling a bit with MEDIA_ROOT and whatnot, but I think I have it right:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
)
MEDIA_URL = "image_upload/"
MEDIA_ROOT = os.path.join(BASE_DIR, "image_upload")
CKEDITOR_UPLOAD_PATH = 'uploads/'
CKEDITOR_IMAGE_BACKEND = "pillow"
CKEDITOR_UPLOAD_SLUGIFY_FILENAME = False
My urls.py, including my attempt at cleaning up the linked answer:
from django.conf import settings
from django.conf.urls import url, include
from django.conf.urls.static import static
from django.contrib import admin
from mainsite.views import HomepageView, AboutView, ContactView
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
url(r'^admin/', admin.site.urls, name="admin"),
url(r'^$', HomepageView.as_view(), name="homepage"),
url(r'^about/', AboutView.as_view(), name="about"),
url(r'^contact/', ContactView.as_view(), name="contact"),
url(r'^blog/', include("blog.urls", namespace="blog")),
url(r'^ckeditor/', include('ckeditor_uploader.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if settings.DEBUG:
urlpatterns += [
url(r'^media/(?P<path>.*)$',
'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}
),
]
urlpatterns += staticfiles_urlpatterns()
Using CKEDITOR_UPLOAD_PATH = 'uploads/' makes django-ckeditor to upload an image to /media/uploads/, like:
settings.py:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static/'),
]
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
CKEDITOR_UPLOAD_PATH = 'uploads/'
When using the Django's dev server, static files are served by default but not media files, so you can force the server to consider them, the url configuration below should work.
urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.views.static import serve
from .views import HomeView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', HomeView.as_view(), name='home'),
url(r'^ckeditor/', include('ckeditor_uploader.urls')),
# serving media files only on debug mode
if settings.DEBUG:
urlpatterns += [
url(r'^media/(?P<path>.*)$', serve, {
'document_root': settings.MEDIA_ROOT
}),
]
The missing function patterns from the old example was an old function I believe used on Django 1.6 or 1.7.
After installing ckeditor, perform the following :
In Settings.py:
add 'ckeditor' and 'ckeditor_uploader' into INSTALLED_APPS.
Add CKEDITOR_UPLOAD_PATH = 'uploads_directory/'
(Do not join MEDIA_ROOT with the upload_directory, ckeditor will take the MEDIA_ROOT as its root upload directory)
In your models files:
USE : from ckeditor_uploader import RichTextUploadingField and modify your required model field to type RichTextUploadingField
In urls.py:
add re_path(r'^ckeditor/', include('ckeditor_uploader.urls')) into urlpatterns
Using Django 1.8 with django-ckeditor 5.3.0, I was getting the exact same symptoms as those above (uploading files worked, but the src attribute of the <img> tag was set incorrectly, causing a red "X" in the preview and broken image links upon publication).
In my case, however, I didn't have to change anything in urls.py. My problem was that I had:
CKEDITOR_UPLOAD_PATH = os.path.join(MEDIA_ROOT, "ckeditor")
So my mistake was giving CKEDITOR_UPLOAD_PATH the path where I wanted ckeditor to upload to (logical, no?).
The fix was to change the above line to
CKEDITOR_UPLOAD_PATH = "ckeditor"
In hindsight I can see how this allows django-ckeditor the ability to use the MEDIA_ROOT for uploading and the MEDIA_URL for serving. Still I thought someone should say it: "Don't use the full path when setting CKEDITOR_UPLOAD_PATH!"
I hope this saves others some time.
For Django 4 the steps to enable image or file upload in django-ckeditor is:
1. Install django-ckeditor
pip install django-ckeditor
2. Update settings.py
Add file upload path:
CKEDITOR_UPLOAD_PATH = "uploads/"
Add ckeditor,ckeditor_uploader in INSTALLED_APPS:
INSTALLED_APPS = [
...
# plugins
'ckeditor',
'ckeditor_uploader'
]
3. Update urls.py
Add path('ckeditor/', include('ckeditor_uploader.urls')) in urlpatterns:
urlpatterns = [
...
path('ckeditor/', include('ckeditor_uploader.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
4. Use RichTextUploadingField in models
from ckeditor_uploader.fields import RichTextUploadingField
class ResearchTopic(models.Model):
title = models.CharField(max_length=200)
description = RichTextUploadingField()
Tested with:
Django==4.0.4
django-ckeditor==6.4.0
References:
django-ckeditor documentation
The #Mohammed-tayab's solution worked for me with a little modification:
from ckeditor_uploader.fields import RichTextUploadingField
Not sure what I'm doing wrong, but I can't get this to work. I'm using Django 1.3 and Python 2.7.
My project structure looks like this:
project
static
templates
settings.py
apps
...
In my settings.py file I have
PROJECT_ROOT = os.path.realpath(os.path.dirname(__file__))
STATIC_ROOT = os.path.realpath(os.path.join(PROJECT_ROOT, 'static'))
STATIC_URL = '/static'
my urls.py file:
from django.conf.urls.defaults import *
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^grappelli/', include('grappelli.urls')),
)
urlpatterns += staticfiles_urlpatterns()
In my templates, I'm using {{ STATIC_URL }} which creates the correct path to my files, like this: /static/js/libs/modernizr-2.0.6.min.js.
None of my static files load and I've double checked the directory structure is correct. I feel like I'm taking crazy pills, so any advice is appreciated. Thanks
You should add the complete path to the dir where you place your static files in STATICFILES_DIRS in settings.py, like this:
STATICFILES_DIRS = (
'/path/to/static',
)
Either add STATICFILES_DIRS as in previous answer or put the package directory that has 'static' dir in your INSTALLED_APPS because django will automatically serve any static dir in apps during development. If your project directory is not on python path and you're not planning to make it importable then you have to define STATICFILES_DIRS and put absolute path to the static directory.