IT Блог

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

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

Выравнивание блоков по высоте в адаптивных сайтах

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

$(function(){
    function get_max_height($elements){
        var max = $elements.eq(0).outerHeight();
        $elements.each(function(index){
            if (index > 0 && max < $(this).outerHeight()) max = $(this).outerHeight();
        });
        return max
    }

    function set_delay_height(){
        // ugly hack for set height
        var resize_intervals = [100, 200, 1000];
        for (var i in resize_intervals){
            setTimeout(function(){
                $(window).resize();
            }, resize_intervals[i]);...

Чистка логов mailer

Штатных средств по очистке логов mailer-а почему-то нет. Но можно написать свою и добавить в cron:

# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
from django.core.management.base import BaseCommand
from mailer.models import MessageLog


class Command(BaseCommand):
    def handle(self, *args, **options):
        file_life = 5  # срок жизни лога
        MessageLog.objects.filter(when_attempted__lte=datetime.now().date() - timedelta(days=file_life)).delete()

В cron можно добавить строчку:

11 1 * * 0 python path/to/manage.py clear_logs

NoReverseMatch: Reverse with arguments and keyword arguments '{}' not found. 0 pattern(s) tried: []

Периодически получаю ошибку подобного плана:

NoReverseMatch: Reverse for 'my_url_name' with arguments '(u'...',)' and keyword arguments '{}' not found. 0 pattern(s) tried: []

И не сразу врубаюсь почему не работает. Вот и решил записать шпаргалочку. Проверить:

1. Включён ли urls.py приложения в корневой urls.py

urlpatterns = patterns('',
    ...
    url(r'^my_app/', include('my_app.urls')),
    ...
)

2. Прописан ли url в urls.py приложения:

urlpatterns = patterns('',
    url(r'^my-url-name/(?P<my_object_id>\d+)/$', my_app.views.my_view, name='my_url_name'),
)

3. Добавлены ли необходимые аргументы в urls.py

urlpatterns = patterns('',
    url(r'^my-url-name/(?P<my_object_id>\d+)/$', my_app.views.my_view, name='my_url_name'),
)

4. Добавлены ли необходимые аргументы при вызове функции url в шаблоне или reverse в коде python

# in template.html...

InvalidBasesError: Cannot resolve bases for [<ModelState: 'cms.PageUser'>]

Довольно-таки необычная может возникнуть ошибка при попытке создать первую миграцию для кастомной модели пользователя (User) в Django:

django.db.migrations.state.InvalidBasesError: Cannot resolve bases for [<ModelState: 'cms.PageUser'>]

Как оказалось, всё дело в том, что django cms в 0001_initial.py миграции пытается обратиться к миграциям модели User:

class Migration(migrations.Migration):

    dependencies = [
        ('auth', '__first__'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),  # обращение к миграциям модели User
        ('sites', '__first__'),
    ]
    ...

И не находит, так как у нас ещё нет пока миграций для нашей модели кастомного юзера. Поэтому перед созданием миграций кастомного пользователя, нужно закомментировать приложения djangocms_text_ckeditor и cms:

INSTALLED_APPS = (
    ...
    'django.contrib.auth',
    'my_custom_auth',  # наша кастомная модель
    ...

    #...

Вывести список изменённых страниц django cms

Простой способ вывести список изменённых страниц в django cms заключается в построении запроса через модель Title:

dirty_titles = Title.objects.filter(publisher_is_draft=True, publisher_state=PUBLISHER_STATE_DIRTY)

В шаблоне результат можно вывести так:

{% if dirty_titles %}
    <p style="font-weight: bold;">Не опубликованы изменения следующих страниц:</p>
    {% for title in dirty_titles %}
        <p class="changelink"><a target="_blank" href="{{ title.page.get_absolute_url }}">{{ title.page.get_title }}</a></p>
    {% endfor %}
{% endif %}

Если у вас мультиязычный сайт, то нужно предусмотреть группировку по языкам (данное свойство находится в экземпляре модели Title). Или же можно результат сделать похожим на структуру страниц django cms.

Моей задачей было вывести в некоторый информационный блок "Оповещения" напоминания о неопубликованных изменениях на...


Убрать кнопку добавить в django

Есть несколько способов убрать кнопку "Добавить" в админке Django. Каждый способ хорош под конкретную задачу.

Ограничение прав на редактирование объекта

Создать в админке группу "Могут просматривать" и добавить нужные права (например, только на изменение объекта), тем самым ограничивая права на создание объектов. А затем необходимым пользователям добавить эту группу.

Мне не особо нравится такой способ. Он мне кажется долговатым, и к тому же иногда хочется, чтобы и суперпользователи не видели эту кнопку.

Переопределение метода has_add_permission

Для конкретной модели в ModelAdmin можно запретить добавлять объект:

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
     def has_add_permission(self, request):
        return False

Этот метод хорош, но бывает, что есть функциональность,...


Using cached IOError: [Errno 28] На устройстве не осталось свободного места

Довольно-таки неочевидная может быть ошибка IOError: [Errno 28] На устройстве не осталось свободного места. Ладно, если на устройстве действительно нет места. А если видишь, что место более чем достаточно, и получаешь такую ошибку? Загадка..

Вот и я сегодня получил такую ошибку, когда стал развёртывать на сервере сайт клиента. При создании виртуального окружения лог был следующим:

Collecting psycopg2==2.5.4 (from -r /home/client/project/src/requirements.txt (line 1))
Collecting Django==1.8.4 (from -r /home/client/project/src/requirements.txt (line 3))
  Using cached Django-1.8.4-py2.py3-none-any.whl
Exception:
Traceback (most recent call last):
  File "/home/client/project/src/env/local/lib/python2.7/site-packages/pip/basecommand.py", line 209, in main
    status = self.run(options, args)
  File "/home/client/project/src/env/local/lib/python2.7/site-packages/pip/commands/install.py", line 310, in run
    wb.build(autobuilding=True)
  File "/home/client/project/src/env/local/lib/python2.7/site-packages/pip/wheel.py", line 748,...

Автоматический перевод в верхний регистр в CharField Django

Простой и, возможно, нестандартный способ перевода значения поля CharField в верхний регистр без использования javascript. Суть в следующем: в модели переопределяем метод save(), преобразовывая значение нашего поля в верхний регистр, и добавления стиля полю text-transform: uppercase. Таким образом, мы всегда будем видеть, что введённые буквы заглавные, а переопределение даст нам возможность сохранить символы в верхнем регистре, которые мы можем использовать в шаблоне без повторного преобразования text-transform: uppercase.

А теперь наглядный пример. Допустим, у нас есть одежда, и её размер (M, S, L ...) должен записываться в верхнем регистре как мы привыкли видеть на лейблах одежды.

# models.py
class Product(models.Model):
    ......

Разделить строку на список подстрок в python

Если нужно распарсить строку по какому-то символу, то в простом случае можно воспользоваться функцией split(separator=' '):

a = 'python,django,templates'
b = a.split(',')  # b = ['python', 'django', 'templates']

Но если у нас задача посложнее, например:

a = 'python, django, template   tags'
b = a.split(',')  # b = ['python', ' django', ' template   tags']

то появится проблема лишних пробелов.

Итак, рассмотрим следующую задачу: есть форма с одним полем categories, данные которого можно записывать как через запятую, так и каждую с новой строки. Нужно сформировать список введённых данных. Например, данные поля имеют вид:

python, django cms,   template   tags


templates

Видим, что первая...


Удалить лишние пробелы python

Для удаления всех пробелов в строке достаточно заменить символ пробела на пустую строку:

' word_1   '.replace(' ', '')  # a = 'word_1'
' word_1    word_2 '.replace(' ', '') # a = 'word_1word_2'

Как видно из последнего примера, в таком подходе слова будут слипаться с друг другом, если их несколько.

Вариант с заменой двух пробелов одним тоже не даст нужного результата - нужно несколько раз проводить замену, чтобы убедиться, что остались только одиночные пробелы между словами:

a = ' word_1    word_2 '
a = a.replace('  ', ' ') # a = ' word_1  word_2 '
a = a.replace(' ', ' ')...

Представляю вашему вниманию книгу, написанную моим близким другом Максимом Макуриным: Секреты эффективного управления ассортиментом.

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

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

Попробуйте

Выберите валюту для отображения денежных единиц