What is the most reusable way for the "extends" method in django templates?
I have seen this very often:
{% extends 'base.html' %}
Unfortunately this does not work for me. The ordering of the template loader loads a template from a different app first.
I have a default django project and application created from scratch with Django1.8.
What should I do:
use a different name like 'my_base.html'
alter the ordering of the template loader
other solution?
The easy way to solve this problem is to namespace your templates. Create an application and inside the application directory (where you have the default views.py) create a templates directory, and inside that directory create a subdirectory which is the name of the application.
Imagine you have a project myproj and an app called registration, then you would have:
.
├── manage.py
├── myproj
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── registration
├── admin.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── templates
│ └── registration
│ └── base.html
├── tests.py
└── views.py
Now even if you have another application with a template called base.html, you can always load the specific template you need with {% extends 'registration/base.html' %}
Related
I am trying to make a Django model of a game with fields for a name and also a cover image that is located in the static folder of the app.
def game_covers_path():
return os.path.join(settings.STATIC_URL, 'some_app/games/')
class Game(models.Model):
name = models.CharField(max_length=100, primary_key=True)
cover = models.FilePathField(path=game_covers_path, null=True)
def __str__(self):
return self.name
My folder structure is as follows:
.
├── db.sqlite3
├── my_app
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── some_app
├── __init__.py
├── admin.py
├── apps.py
├── migrations
├── models.py
├── static
│ └── some_app
│ ├── games
│ │ ├── Counterstrike:\ Global\ Offensive.jpg
├── templates
├── tests.py
├── urls.py
└── views.py
But when I open the admin page I get the following error:
FileNotFoundError at /admin/some_app/game/add/
[Errno 2] No such file or directory: '/static/some_app/games/'
How can I correctly reference images in the static folder of an app in the database? Also does the FilePathField check if the a file exists before saving a model? Because I tried adding random values and it saved it, but in the documentation its written that you can only choose a file that already exists...
(too long for comment)
STATIC_URL is an URL which will be mapped to STATIC_ROOT path by Django in runtime, so use STATIC_ROOT to build file path
static files are not supposed to be dynamically modified: css, js, favicon; what you are trying to do is called media files in terms of Django so use to MEDIA_URL, MEDIA_ROOT instead. Also note, whereas static files are fine to be stored in project folder, media files are usually stored somewhere else. They are not part of your project/solution - they are data.
To handle properly both static and media files you must configure STATIC_ROOT, STATIC_URL, MEDIA_ROOT, MEDIA_URL
There are dozens of questions and answers related to Django static and media files here on SO, please have a look at them. And please take a look at the docs.
Pieces of JSON Schema are easily used with frontend JavaScript libraries like Angular, React and Alpaca to create an html form with validation. This should also work with a Python solution django-jsonschema-form or django-schemulator but I am new to Django and having a lot of trouble working it out..
Here is a screenshot from the video from AlpacaJS which communicates easily what this is supposed to achieve:
I have done some testing with the two libraries above, and the former seems much better maintained and less buggy, the only one of the two in PyPI.
My directory tree created by Django 1.11.4 looks like this:
.
├── db.sqlite3
├── jschemaforms
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
├── myproject
│ ├── __init__.py
│ ├── settings.py
│ ├── templates
│ │ ├── base.html
│ │ └── includes
│ ├── urls.py
│ └── wsgi.py
└── README.md
The docs for django-jsonschema-form specify a class:
# Overriding widgets for all instances of JSONField on PageAdmin form
class PageAdmin(admin.ModelAdmin):
formfield_overrides = {
JSONField: {'widget': JSONSchemaWidget(schema)}
}
Whereabouts in the directory tree is such a class supposed to go?
schema is the piece of json you feed it to define your form
I had a look at the various answers in this SO question to try to work it out:
Django Admin - Overriding the widget of a custom form field
It seems that forms.py and the ModelAdmin object are enough to implement this, but am not sure where in the tree the ModelAdmin object is supposed to live.
How can this be achieved with Django?
rendering the form from jsonschema
validating on client side what the user puts into the form against the jsonschema
retrieving the data from the form POST request when the user clicks 'submit' as json
I am not sure if those two libraries are the answer..
The PageAdmin class goes in a file called admin.py, next to its corresponding model.py. Here are the Django 1.11 docs on discovering admin files.
You also have to register the admin for your model. You use the django.contrib.admin.register
decorator for this. The same page has the docs for this decorator as well.
The usage goes something like
from somewhere import Page
from django.contrib import admin
# Overriding widgets for all instances of JSONField on PageAdmin form
#admin.register(Page)
class PageAdmin(admin.ModelAdmin):
formfield_overrides = {
JSONField: {'widget': JSONSchemaWidget(schema)}
}
This code snippet registers your PageAdmin class as the ModelAdmin for your Page model.
I've recently started studying Django(ver 1.9), and have a question about templates inheritance.
Suppose I have a Django project named mysite and an app named myapp.
And I created base template named base.html and another one named child.html, which inherits base.html.
So directory structure is like this:
(project root)
├── mysite
│ ├── settings.py
│ ├── urls.py
│ └── ...
├── myapp
│ ├── models.py
│ ├── views.py
│ ├── ...
│ └── templates
│ └── myapp
│ ├── base.html
│ └── child.html
└── manage.py
In this situation, I can inherit base.html like this.
<!-- on top of `child.html` -->
{% extends "myapp/base.html" %}
What I'm wondering is, I'm hard-coding the application name.
Are there any other ways of writing that avoid hard-coding the app name?
Or, it's OK and I don't need to worry about?
I came up with some workarounds.
1) Place base.html directly under templates directory
├── myapp
│ ├── models.py
│ ├── views.py
│ ├── ...
│ └── templates
│ ├── base.html # Here!
│ └── myapp
│ └── child.html
--> I think it causes file name crashing between applications.
2) Place base.html under project templates directory
-->In this case I don't want to share base.html between applications.
(base.html here is only for myapp, not other applications)
Both your base template and your child template are specific to your app, so both should live in the same myapp/ subdirectory. It's entirely acceptable to hard-code the dependency on myapp/base.html.
How about
|── myapp
│ ├── models.py
│ ├── views.py
│ ├── ...
│ └── templates
│ ├── base.html # Here!
│ └── child.html
│
then use
<!-- on top of `child.html` -->
{% extends "base.html" %}
Then dynamically changing your Template directory at the beginning of each views.py file.
from django.conf import settings
settings.TEMPLATE_DIRS =(os.path.join(settings.BASE_DIR,'myapp/templates').replace('\\','/'),)
You will have to do the same for every one of your apps.
I know there have been many questions here on accessing static files in a Django project, but I could not find a satisfactory answer to a problem I am dealing with. So, here's my project structure:
.
├── project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
├── db.sqlite3
├── manage.py
└── app
├── admin.py
├── __init__.py
├── migrations
│ ├── __init__.py
├── models.py
├── static
│ └── app
│ └── file.txt
├── tests.py
├── urls.py
└── views.py
As per Django 1.7 documentation I have stored the static file file.txt in app/static/app folder. Now, how do I reference this file in a view? Lets just say I need to read the contents of this file for every call defined in app/views.py.
As usual, I have default setting of STATIC_URL = '/static/' in project/settings.py
Thanks
You can import the static template tag into your view and use it as such:
from django.templatetags.static import static
url = static('app/file.jpg')
You can do this by defining STATIC_ROOT in your settings. Then before running your project you can run
python manage.py collectstatic
And the static files then can be accessed using:-
file = open(os.path.join(settings.STATIC_ROOT, 'app/a.txt'))
This is basically the way, it is supposed to be done in a production environment, as static files are hosted separately from the django html views.
To load the name of app dynamically in project/urls.py
url(r'^', include('app.urls', app_name="app")),
and then in views:-
from django.core.urlresolvers import resolve
def appname(request):
return resolve(request.path).app_name
I'm working through the official Django tutorial. At the end of part two they have you customize the admin template just a bit (changing some heading text). I think I've done everything right, but apparently I haven't because the admin site looks exactly the same after running syncdb and restarting the server. My project directory (excluding the virtualenv part) looks like this:
mysite
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── settings.py
│ ├── settings.pyc
│ ├── urls.py
│ ├── urls.pyc
│ ├── wsgi.py
│ └── wsgi.pyc
├── polls
│ ├── admin.py
│ ├── admin.pyc
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── models.py
│ ├── models.pyc
│ ├── tests.py
│ └── views.py
└── templates
└── admin
└── base_site.html
In settings.py I have these lines added to make the project use the template in templates/admin:
import os
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
later:
TEMPLATE_DIRS = (os.path.join(PROJECT_PATH, 'templates'),)
I've tried several combinations of slashes and variations on assigning the value to PROJECT_PATH and TEMPLATE_DIRS, but haven't gotten anything to work. Each time I verified that it was actually making a filepath string (with a simple print statement).
To try to see what was going on I edited the original Django base_site.html it its admin folder and that changed my site, so it's obviously still using that. I've read several SO posts, and I don't really know what to do anymore.
Oh, and if it's relevant: Python 2.7.3 and Django 1.4.3
First thing I would try is deleting your *.pyc files they often contain stale information which sometimes can cause issues likes this.
If that isn't the case I would then double check your PROJECT_PATH which I believe is the issue here.
dirname gets you the containing directory. so if that line is in the settings.py it will return /path/to/inner/mysite the one inside the main mysite and since there is not templates directory in your inner mysite it wont work.
what you need to do is this.
PROJECT_PATH = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))
Which will return you the outer mysite path when combined with templates it will return you the correct path.
Everything should then work.