How to structure a very small Django Project? - python

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!

Related

Override wagtail BaseSiteSetting template

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.

Multiple Django apps sharing the same URL patterns

I have multiple apps that share almost the same URL patterns, defining almost the same views. Currently i have a urls.py for each app to serve its routing. What i want to do is to group the similar patterns into a single shared_urls.py file then use it in those apps.
To make it easy to understand, suppose (just an example here) i have a blog app and an archive app.
They both define a pattern and view for /post, /comment and /user. So instead of each of them having its own urls.py defining the same pattern, i want to define these patterns in one place then use it in each of the apps, while loading the correct app view.
Current Vs Wishing
Current
project urls.py
url(r'^blog/', include('blog.urls')),
url(r'^archive/', include('archive.urls')),
blog urls.py
url(r'^post/', views.post),
url(r'^comment/', views.comment),
url(r'^user/', views.user),
archive urls.py
url(r'^post/', views.post),
url(r'^comment/', views.comment),
As you see the two apps share almost the same patterns but each has its own implemented view.
Wishing
project urls.py
url(r'^blog/', include('blog.urls')),
url(r'^archive/', include('archive.urls')),
shared_urls.py
#How to bind with the correct app's view!
url(r'^post/', views.post),
url(r'^comment/', views.comment),
blog urls.py
url(r'^user/', views.user),
url(r'', include(shared_urls)),
archive urls.py
url(r'', include(shared_urls)),
This is a logic (controller/view) matter, not a url (routing) matter. Sharing URLs would be a bad practice. They should be clearly separately defined since they provide different actions. The fact that you want to use the same logic/content behind two different url must be handled in your views.

django auth: password change template customization

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.

Django authentication on a per-app basis

I am getting started with Django and I found something I don't understand very well when it comes to user authentication (using the typical django.contrib.auth mechanism).
When I create a "site" using
django-admin.py startproject mysite
I understand I create something like a "server". Then, I need to create an app (as explained in the "getting started" tutorial). I create my models for the app, not for the server. The idea I have (which may be totally wrong) is that apps are something fairly independent among themselves (pretty isolated from each other). I create my models for each app, there is a different set of "views" per app, etc.
But when it comes to user management, that managing seems to be global for the whole project (or "server"): All the settings are specified through the global settings.py file, the built-in login pages are stored in the global templates/ directory... What if I have two apps and I want the login pages for them to have a different aspect? What if after a successful login, I want to redirect to an specific page of app#1 or to another specific page of app#2 depending on the app the user was trying to log in? Maybe I am missunderstanding the whole concept behind a Django app?
Basically, I have a mystartapp application inside a project called myserver. I am using the built-in login view, sending a form to "django.contrib.auth.views.login". With the default configuration, a successful login was trying to redirect me to http://127.0.0.1:8000/accounts/profile/, which I don't have.
I could find a workaround by editing the global settings.py file and the global urls.py files:
---------- settings.py ----------
[ . . . ]
# User Logging in Settings
LOGIN_URL = '/login'
LOGIN_REDIRECT_URL = '/'
[ . . . ]
---------------------------------
and
------------ urls.py ------------
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'myserver.views.home', name='home'),
# url(r'^myserver/', include('myserver.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
#The following line will include the urls for the "mystartapp" application
url(r'^s', include('mystartapp.urls', namespace="mystartapp")), #Dirty trick
url(r'^mystartapp/', include('mystartapp.urls', namespace="mystartapp")),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
url(r'^login/$', 'django.contrib.auth.views.login'),
)
------------------------------
This way, thanks to the 10th line (the one with the #'Dirty trick' comment), everything that goes to the root of 127.0.0.1:8000/ will be redirected to the same set of urls as if I used 127.0.0.1:8000/mystartapp/, which combined with the LOGIN_REDIRECT_URL = '/' option in settings.py, will end up making the browser to redirect to 127.0.0.1:8080/mystartapp/index.html, after a correct login but that doesn't seem "clean".
Is there a better way of establishing a redirection to 127.0.0.1:8080/mystartapp/index.html? Is the dirty trick really a dirty trick or is it the way it's supposed to work? Am I missing something here? (I'm pretty sure the answer to this last question is "Yes!", though)
Thank you in advance.
Is there a reason why using LOGIN_REDIRECT_URL = '/mystartapp/index.html' wouldn't work in your case?
Regarding the concept of apps, they are supposed to be independent bits of functionality (which is why they are sometimes labelled "reusable"). However, once you tie apps into a project, the goal is that they do work together at some point !
In the case of contrib.auth, this reusability is expressed by the parameters you used (such as LOGIN_URL or LOGIN_REDIRECT_URL), which allows you to configure the behavior of the app so it works in your project.
For instance, for a merchant side, you could use several apps to perform different actions related to your project:
An app with your actual functionality (products, pages...)
An app for search (like django-solr)
An app for registration (django-registration)
Contrib apps for authentication, session
A merchant app for payments
The apps perform different bits of functionnality, but they all serve the same purpose and make up a project together.
If you need the apps to operate in a totally independent manner, they shouldn't be part of the same project in the first place! (Although you could use app A in projects P and Q, and app B only in P, for example).

Custom django admin templates not working

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!

Categories