14 апреля 2013 г.

django: не разрешать формам в formset быть пустыми

В django при использовании formset по умолчанию* действует такая штука: при сохранении всего formset незаполненные формы (полностью незаполненные) в нём игнорируются и валидируются/сохраняются только остальные. Если по какой-то причине это неудобно (у меня, например, нужно было заполнять минимум N форм в формсете), то можно отключить, установив empty_permitted = False.

* На самом деле ставится некоторым (extra) формам при конструировании formset, что в общем-то логично.

В документации на этот счёт сказано: «The formset is smart enough to ignore extra forms that were not changed».

Можно намертво прописать в конструкторе формы, например.
class BlablaForm(forms.ModelForm):
    class Meta:
        model = Blabla

    def __init__(self, *arg, **kwarg):
        super(BlablaForm, self).__init__(*arg, **kwarg)
        self.empty_permitted = False

7 апреля 2013 г.

Самодельный упрощённый accordion на jquery

Нужна была схлопывалка дивов, с заголовками, раскрывающая содержимое по очереди. Изначально был код на jquery-ui через accordion, но мучение со стилями достало. Т.к. стили наворачиваются хардкорно, а переопределять все в css получается в несколько раз длиннее, чем сам код.
$( "#accordion" ).accordion({
  active: false,
  collapsible: true,
  header: ".accordion_later",
  heightStyle: "content",
  beforeActivate: function( event, ui ){
   ui.newHeader.hide();
   ui.oldHeader.show();
  }
 });
Рабочий пример: http://jsfiddle.net/Fx4nA/
Потом переделал тупо на jquery, получилось в несколько раз короче.
$('#accordion .collapsible').hide();
$('#accordion .accordion_later').bind('click', function (e) {
    // show all "more..."
    $('#accordion .accordion_later').show();
    // close all collapsible
    $('#accordion .collapsible').slideUp();
    // hide current "more..."
    $(e.target).hide();
    // open current collapsible
    $(e.target).next('div').slideDown();       
});
Рабочий пример: http://jsfiddle.net/8qtXH/

5 апреля 2013 г.

jquery ui dialog без заголовка

Убрать заголовок можно переопределив класс ui-dialog-titlebar, но чтобы не испортить все диалоги сразу можно выборочно через dialogClass.
dialogdiv.dialog({
...
    dialogClass: 'dialog-wo-title',
...

Потом скрываем и всё.
.dialog-wo-title .ui-dialog-titlebar
{
    display:none;
}
Или убираем всё кроме кнопки закрытия (которая остаётся справа)
.dialog-wo-title .ui-dialog-titlebar
{
    width: 0px;
    float: right;
}

22 марта 2013 г.

mysql 5.6 grant ERROR 2013 (HY000) Lost connection to MySQL server during query

После перехода с 5.5 на 5.6 при попытках некоторых операций, например, GRANT вываливает:
ERROR 2013 (HY000): Lost connection to MySQL server during query
Всё потому что нужно не забывать про:
# mysql_upgrade

7 декабря 2012 г.

archlinux перевод на systemd

Как известно, archlinux к данному моменту почти полностью перешёл на systemd. Старый механизм sysvinit/initscripts тоже почти полноценно пока поддерживается через костыли. Чтобы вату не катать, я тоже стал переходить. В данный момент переход довольно подробно описан на арчвики, но на момент накидывания черновика этой заметки всё только начиналось, к тому же у меня чуть более сложный случай, т.к. стояло несколько специфических сервисов итд. Чтобы сразу всё не сломалось (а оно может даже если ничего не трогать), переходить решил постепенно, в принципе, на арчвики так же рекомендовано сейчас.

17 ноября 2012 г.

django: пролучить комментарии для объекта

Комментарии в django.contrib.comments, как известно, привязаны к моделям приложений через джанговский contenttypes. В документации рассказано как отрендерить и получить список в шаблонах, но механизм работы более подробно не рассмотрен для того, чтобы работать с комментариями в своих вьюшках. Ничего тут сложного нету, можно получить ContentType и вытащить все комментарии, но есть более удобный метод:
from django.contrib.comments.models import Comment

project_comments = Comment.objects.for_model(Project).filter(object_pk=project.id)
Его тоже можно разглядеть и изучить в исходниках django. Короче, с помощью for_model у CommentManager можно покороче и поудобнее сделать это всё. Содержимое метода вполне очевидно:
def for_model(self, model):
    """
    QuerySet for all comments for a particular model (either an instance or a class).
    """
    ct = ContentType.objects.get_for_model(model)
    qs = self.get_query_set().filter(content_type=ct)
    if isinstance(model, models.Model):
        qs = qs.filter(object_pk=force_unicode(model._get_pk_val()))
    return qs
Также можно обратить внимание, что если есть возможность, то можно передать не модельку, а конкретный экземпляр, тогда фильтровать по object_pk не придётся.

9 октября 2012 г.

django формы ChoiceField пустой выбор

Как ни странно, на данный момент у ChoiceField нет возможности из формы запросто задать пустой вариант выбора, как, например, у ModelChoiceField. Мелкая обёртка на скорую руку делает это аналогично тому, как это работает в ModelChoiceField.
from django import forms

class EmptyChoiceField(forms.ChoiceField):
    def __init__(self, choices=(), empty_label=u"---------", required=True, *args, **kwargs):
        # если не required и указана empty_label
        if not required and empty_label is not None:
            choices = tuple([(u'', empty_label)] + list(choices))
        super(EmptyChoiceField, self).__init__(choices=choices, required=required, *args, **kwargs)