8👍
It seems the settings file would be a reasonable location to store the version number. I don’t believe there is any Django accepted way to store a version number of your personal application. It seems like an application specific variable that you should define.
For more information on getting the version number out of svn: Getting SVN revision number into a program automatically
31👍
I was looking for this exact same question, and found your question. The answer you accepted is not quite satisfactory to me.
I am working with django debugtoolbar, in there you can also show all versions of the apps used. I was wondering how to get the versions of my custom applications to show there as well.
Looking a bit further I found this question and answer:
How to check the version of a installed application in Django in running time?
This answer however does not tell me where to put this __version__
So I looked in to an open application, which does show up in django toolbar.
I looked in to the django restframework code, there I found out:
the version is put in the __init__.py
file
(see https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/init.py)
and it is put here as:
__version__ = '2.2.7'
VERSION = __version__ # synonym
And after this, in his setup.py, he gets this version from this __init__.py
:
see: https://github.com/tomchristie/django-rest-framework/blob/master/setup.py
like this:
import re
def get_version(package):
"""
Return package version as listed in `__version__` in `init.py`.
"""
init_py = open(os.path.join(package, '__init__.py')).read()
return re.match("__version__ = ['\"]([^'\"]+)['\"]", init_py).group(1)
version = get_version('rest_framework')
When using buildout and zestreleaser:
By the way, I am using buildout and zest.releaser for building and versioning.
In this case, above is a bit different (but basically the same idea):
The version in setup.py is automatically numbered by setup.py, so in __init__.py
you do:
import pkg_resources
__version__ = pkg_resources.get_distribution("fill in yourpackage name").version
VERSION = __version__ # synonym
- [Django]-How to create a custom decorator in Django?
- [Django]-How to show a many-to-many field with "list_display" in Django Admin?
- [Django]-Disabled field is not passed through – workaround needed
28👍
There are many places where you can store your app version number and a few methods that allow you to show it in django templates. A lot depends on the release tool you’re using and your own preferences.
Below is the approach I’m using in my current project.
Put the version number into version.txt
I’m storing the app version number in the version.txt file. It’s one of the locations the zest.releaser release tool (that I’m using) takes into account while doing a release.
The whole content of version.txt is just the app version number, for example: 1.0.1.dev0
Read the number to a variable in settings.py
...
with open(version_file_path) as v_file:
APP_VERSION_NUMBER = v_file.read()
...
Create a custom context processor
This paragraph and the following ownes are based on the wonderful answer by bcchun to Can I access constants in settings.py from templates in Django?
A custom context processor will allow you to add the app version number to the context of every rendered template. You won’t have to add it manually every time you render a template (and usually you’ll want to have the version number somewhere in the footer of every page).
Create context_processors.py file in your app directory:
from django.conf import settings
def selected_settings(request):
# return the version value as a dictionary
# you may add other values here as well
return {'APP_VERSION_NUMBER': settings.APP_VERSION_NUMBER}
Add the context processor to settings.py
TEMPLATES = [{
...
'OPTIONS': {
'context_processors': [
...
'your_app.context_processors.selected_settings'
],
},
}]
Use RequestContext
or render
in views
RequestContext and render
populate the context with variables supplied by context_processors you set in settings.py.
Example:
def some_view(request):
return render(request, 'content.html')
Use it in a template
...
<div>{% trans 'App version' %}:{{APP_VERSION_NUMBER}}</div>
....
- [Django]-Specifying limit and offset in Django QuerySet wont work
- [Django]-Can't compare naive and aware datetime.now() <= challenge.datetime_end
- [Django]-Django: Group by date (day, month, year)
12👍
For me the best result/approach is to use the __init__.py
on the project folder, such as
.
├── project_name
│ ├── __init__.py
and later check using the standar way, as said in (PEP396)
>>> import project_name
>>> project_name.__version__
'1.0.0'
- [Django]-Get the list of checkbox post in django views
- [Django]-Is it better to use path() or url() in urls.py for django 2.0?
- [Django]-Django urlsafe base64 decoding with decryption
10👍
I solved this by adding a templatetag to my django project:
in proj/templatetags, added version.py:
from django import template
import time
import os
register = template.Library()
@register.simple_tag
def version_date():
return time.strftime('%m/%d/%Y', time.gmtime(os.path.getmtime('../.git')))
Then, in my base.html (or whichever template), adding:
{% load version %}
<span class='version'>Last Updated: {% version_date %}</span>
- [Django]-Django Model() vs Model.objects.create()
- [Django]-Running ./manage.py migrate during Heroku deployment
- [Django]-Django Admin: Using a custom widget for only one model field
8👍
If using GIT for source versioning, you might want manual promotion of stable
releases, and automatic numbering for development commits.
One why to obtain this in a Django project is:
In “PROJECT/_ init _.py” define:
__version__ = '1.0.1'
__build__ = ''
Then in setting.py do:
import os
import subprocess
import PROJECT
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
try:
PROJECT.__build__ = subprocess.check_output(["git", "describe", "--tags", "--always"], cwd=BASE_DIR).decode('utf-8').strip()
except:
PROJECT.__build__ = PROJECT.__version__ + " ?"
Thus, PROJECT._ build _ will show:
v1.0.1 in stable releases
and
v1.0.1-N-g8d2ec45
when the most recent tag doesn’t point to the last commit (where N counts the number of additional commits after tag, followed by commit signature)
- [Django]-How do I get the object if it exists, or None if it does not exist in Django?
- [Django]-Python vs C#/.NET — what are the key differences to consider for using one to develop a large web application?
- [Django]-How to lookup django session for a particular user?
2👍
- [Django]-How to make Django serve static files with Gunicorn?
- [Django]-Get class name of django model
- [Django]-Creating a model and related models with Inline formsets
1👍
Version info is typically maintained in git commit tags. Else, even git commits and last updated time is a good indicator of which version is running and when it was deployed.
For those using django-rest-framework
and only having an API, you can return both of these; “last updated” as well as “last git commit” using an /api/version
endpoint:
In views.py
:
import os
import time
import subprocess
import json
class VersionViewSet(ViewSet):
def list(self, request):
# ['git', 'describe', '--tags'] # use this for named tags (version etc)
# ['git', 'describe', '--all', '--long'] # use this for any commit
# git log -1 --pretty=format:"Last commit %h by %an, %ar ("%s")"
# {"commit_hash": "%h", "full_commit_hash": "%H", "author_name": "%an", "commit_date": "%aD", "comment": "%s"}
FILE_DIR = os.path.dirname(os.path.abspath(__file__))
git_command = ['git', 'log', '-1', '--pretty={"commit_hash": "%h", "full_commit_hash": "%H", "author_name": "%an", "commit_date": "%aD", "comment": "%s"}']
git_identifier = subprocess.check_output(git_command, cwd=FILE_DIR).decode('utf-8').strip()
git_identifier = json.loads(git_identifier)
last_updated = time.strftime('%a, %-e %b %Y, %I:%M:%S %p (%Z)', time.localtime(os.path.getmtime('.git'))).strip()
return Response({
"last_updated": last_updated,
"git_commit": git_identifier
}, status=200)
In urls.py
:
from myapp.views import VersionViewSet
router = routers.DefaultRouter()
...
router.register(r'version', VersionViewSet, base_name='version')
This creates the endpoint in line with the other endpoints in your API.
Output will be seen like this at http://www.example.com/api/version/
:
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"last_updated": "Mon, 6 May 2019, 11:19:58 PM (IST)",
"git_commit": {
"commit_hash": "e265270",
"full_commit_hash": "e265270dda196f4878f4fa194187a3748609dde0",
"author_name": "Authorname",
"commit_date": "Mon, 6 May 2019 23:19:51 +0530",
"comment": "The git commit message or subject or title here"
}
}
- [Django]-How to subquery in queryset in django?
- [Django]-Django: using blocks in included templates
- [Django]-Django-rest-framework how to make model serializer fields required
1👍
I use this option __import__('project').VERSION
or __import__('project').__version__
. The version is put in the __init__.py
file as everybody said, for example:
proyect_name
| __init__.py
# __init__.py file
VERSION = '1.0.0' # or __version__ = '1.0.0'
Now from everywhere you can get it:
# Error tracking settings
sentry_sdk.init(
...
release=__import__('cjvc_project').VERSION
)
- [Django]-Apache or Nginx to serve Django applications?
- [Django]-Django admin: can I define fields order?
- [Django]-How to copy InMemoryUploadedFile object to disk
0👍
I used a context processor and it looks like this:
import sys
sys.path.append('..')
from content_services import __version__
def get_app_version(request):
"""
Get the app version
:param request:
:return:
"""
return {'APP_VERSION': __version__}
Since the project name is content_services
I have to change the sys path up 1 level so I can import it.
- [Django]-Django set field value after a form is initialized
- [Django]-Django query filter combining AND and OR with Q objects don't return the expected results
- [Django]-Django development server, how to stop it when it run in background?
0👍
In case you use Git and version tagging you can display the application version in admin site header.
Create a version.py
file in the project or any app module:
import os
import subprocess
FILE_DIR = os.path.dirname(os.path.abspath(__file__))
def get_version_from_git():
try:
return subprocess.check_output(['git', 'describe', '--tags'],
cwd=FILE_DIR).decode('utf-8').strip()
except:
return '?'
VERSION = get_version_from_git()
Add the version to admin site header in urls.py
:
from django.contrib import admin
from django.utils.safestring import mark_safe
from utils import version
...
admin.site.site_header = mark_safe('MyApp admin <span style="font-size: x-small">'
f'({version.VERSION})</span>')
If you need to provide the version to external tools like Django Debug Toolbar, you can expose the version in project __init__.py
as suggested above:
from utils import version
__version__ = version.VERSION
VERSION = __version__ # synonym
- [Django]-Threaded Django task doesn't automatically handle transactions or db connections?
- [Django]-Adding django admin permissions in a migration: Permission matching query does not exist
- [Django]-Use Python standard logging in Celery