私はDjangoアプリケーションに取り組んでおり、アプリケーションのバージョンを表示したいと思っています(バグを見つけた人がアプリケーションのバージョンを知っていて、より良いバグレポートを提供できるように)。
Djangoにバージョン番号を保存するための広く受け入れられている方法はありますか(つまり、Djangoではなくアプリケーションのバージョンを意味します)?
私はDjangoアプリケーションに取り組んでおり、アプリケーションのバージョンを表示したいと思っています(バグを見つけた人がアプリケーションのバージョンを知っていて、より良いバグレポートを提供できるように)。
Djangoにバージョン番号を保存するための広く受け入れられている方法はありますか(つまり、Djangoではなくアプリケーションのバージョンを意味します)?
私はこれとまったく同じ質問を探していましたが、あなたの質問を見つけました。あなたが受け入れた答えは私には完全に満足のいくものではありません。
私はdjangodebugtoolbarを使用しています。そこでは、使用されているアプリのすべてのバージョンを表示することもできます。カスタムアプリケーションのバージョンをそこにも表示する方法を考えていました。
もう少し調べてみると、この質問と回答が見つかりました: 実行時にDjangoにインストールされているアプリケーションのバージョンを確認するにはどうすればよいですか?
しかし、この答えはこれをどこに置くべきかを教えてくれません__version__
そこで、djangoツールバーに表示される開いているアプリケーションを調べました。django restframeworkコードを調べたところ、次のことがわかりました。
バージョンは__init__.py
ファイルに入れられます
(https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/ init .pyを参照してください)
そしてそれはここに次のように置かれます:
__version__ = '2.2.7'
VERSION = __version__ # synonym
そしてこの後、彼のsetup.pyで、彼はこれからこのバージョンを取得し__init__.py
ます:https ://github.com/tomchristie/django-rest-framework/blob/master/setup.pyを参照してください
このような:
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')
buildoutおよびzestreleaserを使用する場合:
ちなみに、ビルドとバージョン管理にはbuildoutとzest.releaserを使用しています。
この場合、上記は少し異なります(ただし、基本的に同じ考えです)。
http://zestreleaser.readthedocs.org/en/latest/versions.html#using-the-version-number-in-setup-py-and-as-versionを参照してください
setup.pyのバージョンは、setup.pyによって自動的に番号が付けられるため、次のようにし__init__.py
ます。
import pkg_resources
__version__ = pkg_resources.get_distribution("fill in yourpackage name").version
VERSION = __version__ # synonym
アプリのバージョン番号を保存できる場所はたくさんあり、djangoテンプレートで表示できるようにする方法もいくつかあります。多くはあなたが使用しているリリースツールとあなた自身の好みに依存します。
以下は、現在のプロジェクトで使用しているアプローチです。
アプリのバージョン番号をversion.txtファイルに保存しています。これは、 (私が使用している)zest.releaserリリースツールがリリースの実行中に考慮に入れる場所の1つです。
version.txtのコンテンツ全体は、アプリのバージョン番号だけです。例:1.0.1.dev0
...
with open(version_file_path) as v_file:
APP_VERSION_NUMBER = v_file.read()
...
この段落と次の所有者は、Djangoのテンプレートからsettings.pyの定数にアクセスできますか?に対するbcchunのすばらしい回答に基づいています。
カスタムコンテキストプロセッサを使用すると、レンダリングされたすべてのテンプレートのコンテキストにアプリのバージョン番号を追加できます。テンプレートをレンダリングするたびに手動で追加する必要はありません(通常、すべてのページのフッターのどこかにバージョン番号を付けたいと思うでしょう)。
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}
TEMPLATES = [{
...
'OPTIONS': {
'context_processors': [
...
'your_app.context_processors.selected_settings'
],
},
}]
RequestContext
またはrender
ビューでRequestContextを実行し、 settings.pyrender
で設定したcontext_processorsによって提供される変数をコンテキストに入力します。
例:
def some_view(request):
return render(request, 'content.html')
...
<div>{% trans 'App version' %}:{{APP_VERSION_NUMBER}}</div>
....
djangoプロジェクトにtemplatetagを追加することで、これを解決しました。
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>
私にとって最良の結果/アプローチは__init__.py
、次のようなプロジェクトフォルダでを使用することです。
.
├── project_name
│ ├── __init__.py
(PEP396)で述べたように、後で標準の方法を使用して確認します
>>> import proyect_name
>>> proyect_name.__version__
'1.0.0'
設定ファイルは、バージョン番号を保存するのに適切な場所のようです。個人用アプリケーションのバージョン番号を保存するためにDjangoで受け入れられている方法はないと思います。定義する必要があるアプリケーション固有の変数のようです。
svnからバージョン番号を取得する方法の詳細:SVNリビジョン番号をプログラムに自動的に取得する
ソースのバージョン管理にGITを使用している場合は、安定したリリースの手動プロモーションと、開発コミットの自動番号付けが必要になる場合があります。
Djangoプロジェクトでこれを取得する理由の1つは、次のとおりです。
「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はタグの後の追加のコミットの数をカウントし、その後にコミット署名が続きます)
このオプション__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
)
コンテキストプロセッサを使用しましたが、次のようになります。
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レベル上に変更する必要があります。
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
バージョン情報は通常、gitcommitタグで維持されます。それ以外の場合は、git commitと最終更新時刻でさえ、実行中のバージョンとそれがいつデプロイされたかを示す良い指標になります。
APIを使用django-rest-framework
していて、APIしか持っていない場合は、これらの両方を返すことができます。エンドポイントを使用した「最終更新」と「最終gitcommit」/api/version
:
で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"
}
}