38

我正在开发一个 Django 应用程序,我想显示应用程序的版本(以便发现错误的人知道应用程序的版本并可以提供更好的错误报告)。

是否有一种普遍接受的方式在 Django 中存储版本号(我的意思是我的应用程序的版本,而不是 Django)?

4

11 回答 11

29

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):

see http://zestreleaser.readthedocs.org/en/latest/versions.html#using-the-version-number-in-setup-py-and-as-version

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
于 2013-04-17T08:33:57.993 回答
23

有很多地方可以存储您的应用程序版本号和一些允许您在 django 模板中显示它的方法。很大程度上取决于您使用的发布工具和您自己的偏好。

以下是我在当前项目中使用的方法。

将版本号放入version.txt

我将应用程序版本号存储在version.txt文件中。这是zest.releaser发布工具(我正在使用)在发布时考虑的位置之一。

version.txt的全部内容就是应用的版本号,例如:1.0.1.dev0

将数字读入 settings.py 中的变量

...    
with open(version_file_path) as v_file:
    APP_VERSION_NUMBER = v_file.read()
...

创建自定义上下文处理器

本段和以下内容基于bcchunCan I access constants in settings.py from templates in Django 的精彩回答?

自定义上下文处理器将允许您将应用程序版本号添加到每个渲染模板的上下文中。您不必在每次渲染模板时手动添加它(通常您希望在每个页面的页脚中都有版本号)。

在你的 app 目录中创建context_processors.py文件:

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}

将上下文处理器添加到 settings.py

TEMPLATES = [{
    ...
    'OPTIONS': {
        'context_processors': [
            ...
            'your_app.context_processors.selected_settings'
        ],
    },
 }]

在视图中使用RequestContextrender

RequestContext并使用您在settings.pyrender中设置的 context_processors 提供的变量填充上下文。

例子:

def some_view(request):
    return render(request, 'content.html')
    

在模板中使用它

...
<div>{% trans 'App version' %}:{{APP_VERSION_NUMBER}}</div>
....
于 2016-12-15T13:08:05.190 回答
9

对我来说,最好的结果/方法是使用__init__.py项目文件夹上的,例如

.
├── project_name
│   ├── __init__.py

然后使用标准方式进行检查,如(PEP396)中所述

>>> import proyect_name
>>> proyect_name.__version__
'1.0.0'
于 2014-08-26T14:25:10.063 回答
9

我通过在我的 django 项目中添加一个模板标签来解决这个问题:

在 proj/templatetags 中,添加了 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')))

然后,在我的 base.html(或任何模板)中,添加:

{% load version %}
<span class='version'>Last Updated: {% version_date %}</span>
于 2014-05-10T18:18:41.167 回答
7

设置文件似乎是存储版本号的合理位置。我不相信有任何 Django 接受的方式来存储您的个人应用程序的版本号。这似乎是您应该定义的应用程序特定变量。

有关从 svn 中获取版本号的更多信息:Getting SVN revision number into a program automatically

于 2013-01-29T19:23:38.727 回答
5

如果使用 GIT 进行源代码版本控制,您可能需要手动升级稳定版本,并为开发提交自动编号。

在 Django 项目中获得这个的一个原因是:

在“PROJECT/_ init _.py”中定义:

__version__ = '1.0.1'
__build__ = ''

然后在setting.py中做:

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__ + " ?"

因此,PROJECT._ build _ 将显示:

v1.0.1 in stable releases

v1.0.1-N-g8d2ec45 

当最近的标签不指向最后一次提交时(其中 N 计算标签后的额外提交次数,后跟提交签名)

于 2017-09-15T10:56:13.330 回答
2

不是针对 Django 应用程序本身,而是针对 Python 模块,是的。请参阅PEP 396PEP 386verlib库 ( easy_install verlib )。

(我会详细说明,但我自己现在才发现这一点。)

于 2013-08-19T16:12:55.693 回答
1

我使用此选项__import__('project').VERSION__import__('project').__version__. 正如大家所说,版本放在__init__.py文件中,例如:

proyect_name
  | __init__.py

# __init__.py file
VERSION = '1.0.0' # or __version__ = '1.0.0'

现在你可以从任何地方得到它:

# Error tracking settings
sentry_sdk.init(
    ...
    release=__import__('cjvc_project').VERSION
)
于 2019-07-04T15:53:30.983 回答
0

版本信息通常保存在 git commit 标签中。否则,即使 git 提交和上次更新时间也可以很好地指示哪个版本正在运行以及何时部署。

对于那些使用django-rest-framework并且只有 API 的人,您可以返回这两个;使用/api/version端点的“最后更新”和“最后 git 提交”:

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)

urls.py

from myapp.views import VersionViewSet

router = routers.DefaultRouter()
...
router.register(r'version', VersionViewSet, base_name='version')

这将创建与 API 中的其他端点一致的端点。

输出将如下所示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"
    }
}
于 2019-05-07T02:13:31.057 回答
0

我使用了上下文处理器,它看起来像这样:

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__}

由于项目名称是content_services我必须将 sys 路径更改为 1 级,以便我可以导入它。

于 2018-08-18T01:11:57.307 回答
0

如果您使用 Git 和版本标记,您可以在管理站点标题中显示应用程序版本。

version.py在项目或任何应用模块中创建文件:

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()

将版本添加到管理站点标题中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>')

如果您需要将版本提供给 Django 调试工具栏等外部工具,您可以__init__.py按照上面的建议在项目中公开版本:

from utils import version

__version__ = version.VERSION
VERSION = __version__  # synonym
于 2018-12-31T12:32:02.433 回答