IT Блог

Документации и переводы

Статьи на технические темы

Воспроизвести ошибку в браузере, полученную на почте от Django

Как правило, если возникает 500 ошибка вашего приложения на сервере, то посылается сгенерированный Django-отчёт об ошибке (трейсбек) электронным адресам, указанным в ADMINS в settings.py. Это может выглядеть примерно так:

Internal Server Error: /billing/online_reg_ip/

KeyError at /billing/online_reg_ip/
'birthday_day'

Request Method: POST
Request URL: https://site.ru/billing/online_reg_ip/
Django Version: 1.10.7
Python Executable: /usr/bin/uwsgi-core
Python Version: 2.7.9
Python Path: ['/path_to_project/src/', '.', '', ...]
Server time: Ср, 21 Мар 2018 08:40:50 +0800
Installed Applications: (u'django.contrib.contenttypes', ...)
Installed Middleware: (u'django.middleware.cache.UpdateCacheMiddleware', ...)

Traceback: 
File "/path_to_projet/env/local/lib/python2.7...

AttributeError: Module Pip has no attribute 'main'

Начиная с pip версии 10.X, появляется ошибка при вызове функции pip.main():

AttributeError: Module Pip has no attribute 'main'

Функция main() переехала в модуль _internal (pip._internal), поэтому можно откатить pip до версии 9.X, например так:

pip install --upgrade pip==9.0.3

Или импортировать main() из _internal:

from pip._internal import main

Если у вас на разных машинах (напр, на локальной и боевой, как было в моём случае) стоит pip разных версий, то можно воспользоваться отлавливанием исключения ImportError:

try:
    from pip._internal import main
except ImportError:
    from pip import main

PROJECT_ROOT = abspath(dirname(__file__))
main(['install', '-r...

help_text field admin django

help_text для кастомного поля

Иногда хочется добавить help_text для своего кастомного поля в админке Django, например так:

from django.contrib import admin

class MyModelAdmin(admin.ModelAdmin):
    fields = ('title', 'custom_field')

    def custom_field(self, obj):
        # some code...
        return some_result

    custom_field.help_text = _('Custom help text')

Но до сих пор (на момент написания статьи 6 мая 2018 года) для кастомный полей в настройке admin-класса Django такой функции нет. Поэтому самый простой способ добавить вспомогательный текст - сделать это вручную. Например:

from django.contrib import admin

class MyModelAdmin(admin.ModelAdmin):
    fields = ('title', 'custom_field')

    def custom_field(self, obj):
        # some code...
        return '{}<p class="help">{}<...

Отключить кэширование страницы для приложения django-cms

При создании своего кастомного приложения (apphook) в django-cms или при отображении карточки товара в django-shop может кэшироваться страница.

Я столкнулся с такой проблемой, когда мне нужно было после добавления товара в корзину отображать актуальные данные (увеличить счётчик товаров в корзине, вывести сообщение, что товар был добавлен в корзину и т. д.). Чтобы убрать кэш именно в этом месте, достаточно для классового представления (class-based view) ProductRetrieveView.as_view(), который отображает карточку товара, использовать never_cache:

myshop/urls/products.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.conf.urls import url
from django.views.decorators.cache import never_cache
from shop.views.catalog import...

Как заставить Django перезапускать сервер при изменении шаблона?

Команда django runserver умеет определять изменения python-файлов (файлов с расширением .py) и можно подумать, что эта команда не умеет перезапускаться при изменении шаблонов. На самом деле здесь другая тема. Во-первых, нет необходимости перезагружать сервер при изменении шаблонов. А во-вторых, мы не можем наблюдать изменения шаблонов, если они закэшированы. 

По умолчанию, когда в settings.py переменная DEBUG имеет значение False, шаблоны рендерятся каждый раз при загрузке страницы.

Но, если у нас добавляются специфические загрузчики (loaders), например так:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(ROOT_DIR, 'templates'), ],
        'OPTIONS': {
            'loaders': [
                ('django.template.loaders.cached.Loader', [
                    'django.template.loaders.filesystem...

nginx настройка дефолтной страницы

Если на вашем хостинге есть несколько сайтов, то рекомендуется установить дефолтную страницу, которая будет показываться, если какой-то сайт временно не работает (а точнее, если временно удалена/не используется конфигурация nginx для какого-то сайта):

http {
    ...
    include /etc/nginx/sites-enabled/*;

    # default virtual host
    server {
        listen 80 default;
        server_name localhost;
        deny all;

        # добавьте location / {...}, если хотите, чтобы открылась ваша определённая страница вместо стандартного показа ошибки "403 Fobidden"
        location / {
            root   html;
            index  index.html;
        }
    }
    ...
}

Обработка кода ошибки 6 в Вконтакте - Слишком много запросов в секунду

При работе с API в Контакте можно встретить следующий ответ:

{'error': 'Too many requests per second',
 'error_code': 6}

Значение 6 ключа error_code говорит о том, что превышено допустимое количество обращений api в течение некоторого времени (обычно в течение секунды).

Обработать его можно достаточно легко, например:

import requests
import time


def get_vk_data(url, params):
    repeat = True
    while repeat:
        resp = requests.get(url, params=params)
        data = resp.json()

        if 'error' in data and 'error_code' in data['error'] and data['error']['error_code'] == 6:
            time.sleep(2)
        else:
            repeat = False

    return data

Другими словами, мы пытаемся получить ответ (в переменную data) до тех пор...


Перевод тегов в taggit

Для перевода используется пакет parler.

Используйте дополнительное поле title. Не добавляйте перевод полю name для django-taggit, так как на поле name завязано много функциональности

from parler.models import TranslatableModel, TranslatedFields
from taggit.managers import TaggableManager from taggit.models import GenericTaggedItemBase, TagBase, ItemBase

class MyTag(TagBase, TranslatableModel):
    translations = TranslatedFields(
        title=models.CharField(_('Title'), max_length=100),
    )

    @permalink
    def get_absolute_url(self):
        return 'tag_page', (self.slug, )

    class Meta:
        ordering = ('name', )
        verbose_name = _('Tag')
        verbose_name_plural = _('Tags')


class MyTaggedItemBase(ItemBase):
    tag = models.ForeignKey(MyTag, related_name='tag_items', on_delete=models.CASCADE)

    class Meta:
        abstract = True

    @classmethod
    def tags_for(cls, model, instance=None, **extra_filters):
        kwargs = extra_filters or...

node grunt автоматическая компиляция scss

Очень кратка инструкция без пояснений по тому, как в автоматическом режиме компилировать файлы scss.

Если ещё не установили nodejs, то устанавливаем:

apt-get install node
apt-get install npm

После установки NodeJS нужно добавить ссылку на nodejs, так как в debian исполняемый файл называется nodejs (вместо node):

sudo ln -s /usr/bin/nodejs /usr/bin/node

Убедитесь, что установлены пакеты:

sudo apt-get install sass
sudo apt-get install ruby-compass

Создаём в корне проекта package.json:

{
  "name": "grunt-getting-started",
  "version": "0.1.0",
  "devDependencies": {
    "grunt"                    : ">= 0.4",
    "grunt-cli"                : ">= 0.1.6",
    "grunt-contrib-sass": "latest",
    "grunt-contrib-watch": "latest"
  }
}

devDependencies - содержит список необходимых зависимостей.

Создаём в корне...


Перерисовка диаграммы highcharts

Обычно графики highcharts автоматически перерисовываются при изменении размеров окна браузера, но бывают случаи, когда нужно принудительно перерисовать график.

Интуиция подсказывает, что нужно использовать метод .redraw(), но, увы, возможно, это не сработает (как это случилось у меня). Мне, к примеру, нужно было перерисовывать диаграмму после сворачивания левой панели меню. Когда сворачивается или разворачивается меню, то ширина div-а изменяется и нужно автоматически подстраивать графики под новую ширину.

Для перерисовки диаграмм highcharts используйте метод .reflow():

$('..close').on('click.chart', function () {  // вешаем событие click на кнопку сворачивания меню
    var $sb_chart = $('.sb_chart');
    $.each($sb_chart, function () {  // если у вас несколько графиков
        var chart = $(this).highcharts();
        chart...

На данный момент нет специального поиска, поэтому я предлагаю воспользоваться обычной поисковой системой, например, Google, добавив "vivazzi" после своего запроса.

Попробуйте