Номер версии в приложениях Django - программирование
Подтвердить что ты не робот

Номер версии в приложениях Django

Я работаю над приложением Django, и я хочу отобразить версию приложения (так, чтобы люди, которые обнаружили ошибки, знали версию приложения и могли предоставлять лучшие отчеты об ошибках).

Существует ли общепринятый способ хранения номера версии в Django (я имею в виду версию моего приложения, а не Django)?

4b9b3361

Ответ 1

Кажется, что файл настроек будет разумным местом для хранения номера версии. Я не верю, что есть какой-либо Django способ хранения номера версии вашего личного приложения. Это похоже на конкретную переменную приложения, которую вы должны определить.

Для получения дополнительной информации о получении номера версии из svn: Автоматическое получение номера версии SVN в программе

Ответ 2

Я искал точно такой же вопрос и нашел ваш вопрос. Ответ, который вы приняли, не совсем удовлетворителен для меня.

Я работаю с django debugtoolbar, там вы также можете показать все версии используемых приложений. Мне было интересно, как сделать так, чтобы версии моих пользовательских приложений отображались там же.

Глядя немного дальше, я нашел этот вопрос и ответ: как проверить версию установленного приложения в 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

Ответ 3

Есть много мест, где вы можете хранить номер версии вашего приложения, и несколько методов, которые позволяют отображать его в шаблонах 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()
...

Создать пользовательский контекстный процессор

Этот параграф и следующие материалы основаны на замечательном ответе bcchun на " Могу ли я получить доступ к константам в settings.py из шаблонов в Django?"

Пользовательский контекстный процессор позволит вам добавить номер версии приложения в контекст каждого отображаемого шаблона. Вам не нужно будет добавлять его вручную каждый раз, когда вы создаете шаблон (и обычно вам нужно, чтобы номер версии находился где-то в нижнем колонтитуле каждой страницы).

Создайте файл 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'
        ],
    },
 }]

Используйте RequestContext или render в представлениях

RequestContext и render заполняют контекст переменными, предоставленными context_processors, который вы установили в settings.py.

Пример:

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

Используйте это в шаблоне

...
<div>{% trans 'App version' %}:{{APP_VERSION_NUMBER}}</div>
....

Ответ 4

Я решил это, добавив templatetag к моему проекту 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>

Ответ 5

Для меня лучший результат/подход - использовать init.py в папке проекта, например

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

а затем проверить, используя стандартный способ, как указано в (PEP396)

>>> import proyect_name
>>> proyect_name.__version__
'1.0.0'

Ответ 6

Не для приложений Django, как таковых, но для модулей Python, да. См. PEP 396, PEP 386 и verlib библиотека (easy_install verlib).

(Идентификация сложная, но я только что обнаружил это сам).

Ответ 7

При использовании GIT для управления версиями исходного кода может потребоваться ручное продвижение стабильных выпусков и автоматическая нумерация для коммитов разработки.

Одна из причин получения этого в проекте Django:

В "PROJECT/_ init _.py" определите:

__version__ = '1.0.1'
__build__ = ''

Затем в setting.py сделайте:

import os
import subprocess
import PROJECT

BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__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 подсчитывает количество дополнительных коммитов после тега, за которыми следует подпись коммита)

Ответ 8

Я использовал контекстный процессор, и это выглядит так:

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 уровень, чтобы я мог его импортировать.

Ответ 9

Если вы используете 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 Debug Toolbar, вы можете предоставить версию в проекте __init__.py как указано выше:

from utils import version

__version__ = version.VERSION
VERSION = __version__  # synonym

Ответ 10

Информация о версии обычно поддерживается в тегах git commit. Иначе, даже коммиты git и время последнего обновления являются хорошим индикатором того, какая версия запущена и когда она была развернута.

Для тех, кто использует django-rest-framework и имеет только API, вы можете вернуть оба из них; "последнее обновление", а также "последний git commit" с использованием конечной точки /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"
    }
}

Ответ 11

Я использую эту опцию __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
)