I want to theme django auth's password change templates to my site. The problem is that django is seeing the django/contrib/admin/templates/registration/ versions of the templates instead of my beautifully crafted myapp/template/registration/password*.html.
This poster was told to fiddle with app order in settings.py, which is a bit fragile to my taste. I think this poster may have gotten a reasonable answer, but if so, I haven't quite understood it yet.
So what I did was to add a bunch of non-DRY cruft to my urls.py file, copied from auth_urls.py:
# Provide explicit templates where I've provided them, shadowing the URL's
# that registration.backends.defaults.urls will provide.
url(r'^accounts/password/change/$',
auth_views.password_change,
{'post_change_redirect': reverse_lazy('auth_password_change_done'),
'template_name': 'registration/password/change_form.html' },
name='auth_password_change'),
# ...
url(r'^accounts/', include('registration.backends.default.urls')),
This works, but saddens me in its repetition. Surely django encourages something cleaner. Any pointers?
(Fwiw, django 1.7 and python 3.4.2.)
Put this template into your project's templates dir and add the following code to the settings.py.
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),
)
By default django.template.loaders.filesystem.Loader is placed before django.template.loaders.app_directories.Loader in TEMPLATE_LOADERS so project's templates directory has precedence over app's templates.
Related
I've been trying for some time to override the edit.html template for a single BaseSiteSetting in wagtail.
I'm not sure if this is even possible. My overrides for ModelAdmin templates are working just fine by using the following directory structure:
ModelAdmin index.html override
Is the same possible for my setting? Which is located in my success_stories app models.
I've looked through the wagtail/contrib/settings/templates/wagtailsettings/edit.html file but it's unclear to me how to do this. I've always worked with headless wagtail and don't have a lot of experience with templates.
The wagtail docs only seem to mention ModelAdmin overrides.
This would be done via standard Django template overrides: The first template that matches wins the cake.
In your case the template for the Wagtail Settings contrib module is located under templates/wagtailsettings/edit.html which means that in your app's template directory you have to make the exact same setup:
<you_app_directory>/templates/wagtailsettings/edit.html
Then depending on how you have setup your template discovery and/or have setup your app loading order one of the above templates will match first. So in order for your template to be the first one to match you can do two things:
Alter the loading order of your apps and make sure that your app comes before the wagtail.contrib.settings in your INSTALLED_APPS Django settings listing:
INSTALLED_APPS = [
...
<your_app>,
wagtail.contrib.settings
...
]
Or you can alter how templates are discovered by Django by changing the TEMPLATES setting:
TEMPLATES = [
{
...
'DIRS': [BASE_DIR / 'templates'],
"APP_DIRS": True,
...
},
]
Notice that DIRS comes before APP_DIRS, the order here matters as well. First Django will look in the directories you specify in DIRS, if nothing matched it will continue to look in the installed application directories.
Note that with the latter method BASE_DIR / 'templates' is a single templates directory at the root of your project.
Usually, if overriding third-party templates, the first method is used.
I'm having trouble understanding how static files are handled in Django. I've read through the official Django documentation as well as multiple threads, including this wonderful one here:
Differences between STATICFILES_DIR, STATIC_ROOT and MEDIA_ROOT
Most people define the STATICFILES_DIRS list as a list of paths where django will search for additional static files aside from the app's static folder.
I understand that, but what does this have to do with the formfields I'm overriding in my admin.py?
I have overridden the default ManyToMany form to the FilteredSelectMultiple widget in a few of my admin models like so:
from django.contrib.admin.widgets import FilteredSelectMultiple
formfield_overrides = {
models.ManyToManyField: {'widget': FilteredSelectMultiple("User Names", is_stacked=False)}
}
This works fine and produces the widget override I wanted: Functional Widget Screenshot
However, when I define STATICFILES_DIRS in settings.py to include my root static folder like so:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static/'),
)
It breaks my override and defaults back to the original ManyToMany field form:
Broken Widget Screenshot
We do not have STATIC_ROOT defined in our settings.py as we don't plan on using the collect static feature. We plan on keeping/referencing our static files at the root static folder. Also in our settings.py we have:
STATIC_URL = '/static/'
I don't understand how these settings for dealing with static files are interfering with the formfield_override above. I would appreciate some insight on this, so that I could find a way to approach this issue.
Thank you!
I figured out the cause of my issue. I missed this portion in the Django documentation that explains STATICFILES_FINDERS: STATICFILES_STORAGE Documentation
It turns out that my production server was finding the static files in my outer root folder first, which were not up to date. This explains why I wasn't seeing my changes. I'm going to reconfigure the way I handle static files to ensure that the outer root static folder that my production server looks always has the latest static files via the collectstatic feature
It is a little oxymoron now that I am making a small Django project that it is hard to decide how to structure such project. Before I will at least will have 10 to 100 apps per project. Now my project is just a website that presents information about a company with no use database, meaning it's really static, with only 10 to 20 pages. Now how do you start, do you create an app for such project.
meaning it's really static
Use nginx to serve static files. Do not use django. You will setup project structure when it will be required.
If you only have static views, you can use the following setup:
A settings file
urls.py
templates/ folder
wsgi.py
You can use a TemplateView to direct any url to the appropriate (static) template:
from django.views.generic import TemplateView
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='home.html'), name='home'),
...
]
Then point the ROOT_URLCONF setting to your urls.py, and add the templates/ folder to your TEMPLATES setting. Add any other required settings such as SECRET_KEY or ALLOWED_HOSTS, and configure your wsgi.py.
Frankly I won't use Django in that case, I would use Flask for such small projects. it's easy to learn and setup a small website.
PS: I use Flask in small and large apps!
I'm in the process of setting up my views in Django, but I'm confused about how to link it to my pageOne.html page so it shows that instead of the "Welcome" page. Currently, when I run the server using python manage.py runserver 127.0.0.2:8001 I get an error message that says "Template Does Not Exist at" pageOne.html.
I've set
TEMPLATE_DIRS = (os.path.join(os.path.dirname(BASE_DIR), "static", "templates"))
I've also tried
TEMPLATE_DIRS = ('/Users/andrewnguyen/Desktop/Websites/gale/python/techExercise/templates',)
but that hasn't really worked either.
Update:
Here's a screenshot. I imagine that my error is somewhere in my urls, settings or views.py. I've changed the path to my TEMPLATE_DIRS as mentioned in the comment below. That did not work. I've included an image of my file structure on Imgur: http://imgur.com/kR1xcGJ
Your TEMPLATE_DIRS settings should look like this:
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, "templates"),
)
Update
After looking at that screenshot you posted, I can say you've made a lot of mistakes.
The templates folder is inside the static folder.
Move the templates folder out of the static folder.
There's a mistake in the return statement of your view.
It should look like this:
return render(request, 'pageOne.html')
There's no need to prepend /static/templates/ to the template name. Django automatically looks for templates in your settings' TEMPLATE_DIRS path.
And finally, nothing you're doing is very difficult. All these mistakes are caused by ignorance, since everything is mentioned elaborately in the docs. Please read them carefully.
I've been trying to get custom templates for the admin page for Django working but have been unsuccessful. I've read the django documentation and several blogs which explain it as being such an easy step, which I assumed it was.
As of right now the admin page works but my own rewrite of the CSS or templates is not working. My setup is as follows
/project_folder/
manage.py
settings.py
urls.py
__init__.py
/app/
views.py
models.py
__init__.py
/templates/
/admin/
base_site.html
In the urls.py I have
(r'^admin/', include(admin.site.urls)),
Which works since I cannot login etc. So I am assuming the /admin/base_site.html would overwrite the default one but it isn't doing a thing.
Anyone know what is going on here ? I followed it from the Django tutorials/guides and went onto some blogs to see if they had answers but they all said the same thing.
Edit 1:
I do have my templates directory setup correctly.
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'templates/'),
)
This works correctly as I have the rest of my site working with a media directory for CSS etc. The only thing not seeming to 'accept' the templates is the admin section.
Alright I fixed it, this was a stupid mistake but I was already playing with this for the past 2 hours. I had to declare my app before django.contrib.admin. It wouldn't accept it otherwise.
One more mistake that one should resist making on this exercise. The exercise says to change this...
<h1 id="site-name"> {{ site_header|default:_('Django administration') }} </h1>
to this...
<h1 id="site-name">Polls Administration</h1>
There is a temptation to only change the string constant, but that is incorrect. I.e. do NOT do this, it will not alter the heading:
<h1 id="site-name"> {{ site_header|default:_('Polls Administration') }} </h1>
That was the mistake I made, and I had to go through the exercise meticulously to fix it.
I couldn't get the admin template to be recognized when doing this step in part two of the Django tutorial.
This is how I solved it:
Using the information in this answer, I printed the value of TEMPLATE_DIRS:
At the command line, navigate to the directory in which the project's settings.py file exists (for me this is R:\jeffy\programming\sandbox\python\django\tutorial\mysite\mysite\)
Start the interactive shell: python
>>> import settings
>>> settings.TEMPLATE_DIRS, which outputs ['R:\\jeffy\\programming\\sandbox\\python\\django\\tutorial\\mysite\\templates']
So this is the expected location of the templates directory for this project. The admin directory goes into that, and the base_site.html file goes into that.
The other problem I had was that it was working, but I only changed the <TITLE> field, so I just didn't notice it. (I thought I was changing the main header.)
I had this same problem walking through the Django 1.6.5 tutorial (https://docs.djangoproject.com/en/1.8/intro/tutorial02/), but realized it was a mistake in not reading carefully. The tutorial has you do is put this into your settings.py:
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...
}
I then put the templates folder I wanted to put override for the admin site under the app just like your example:
/project_folder/
manage.py
settings.py
urls.py
__init__.py
/app/
views.py
models.py
__init__.py
/templates/
/admin/
base_site.html
With this it wouldn't work for the reason similar to the issue you had noted by Daniel Roseman in one of the comments, my DIR was evaluating to project_folder/templates (as I told it to). Then I noticed in the tutorial it explicitly said put the templates/admin folder at the project level, not the app level:
Create a templates directory in your project directory (the one that contains manage.py). Templates can live anywhere on your filesystem that Django can access. (Django runs as whatever user your server runs.) However, keeping your templates within the project is a good convention to follow.
By doing this I had the following structure:
/project_folder/
manage.py
settings.py
urls.py
__init__.py
/templates/
/admin/
base_site.html
/app/
views.py
models.py
__init__.py
With this, the everything worked as expected (I could overwrite the default django templates for the admin pages).
While you should be able to put templates anywhere and configure Django to find them, it seems to makes sense to put your main admin templates at the project level, as the admin site's not app specific, but available for the entire project.
Make sure you have set TEMPLATE_DIRS in settings.py to the correct folder!