5 полезных батареек для Django

    Разрабатывая постоянно сталкиваешься с разнообразными задачами, которые часто решить в лоб не удаётся. Но многие задачи уже были решены кем-то — нужно только найти это решение.

    Так, день за днём я насобирал небольшую коллекцию батареек, которые сильно облегчили мне жизнь. Чем и спешу поделиться:

    django-select2


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

    В ней представлено два типа виджетов:
    • Light — виджеты для не очень длинных списков значений, поскольку сразу все значения рендерятся на страницу;
    • Heavy — продвинутые виджеты для загрузки данных через Ajax из внешнего источника. В качестве такого источника может быть собственный View или же, если не требуется какой-то сложной логики, для отдачи данных может использоваться встроенный в django-select2 View в связке с соответствующим AutoHeavy-виджетом.

    GitHub
    Документация

    django-bitfield


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

    Пример использования (взят из документации):

    from bitfield import BitField
    
    class MyModel(models.Model):
        flags = BitField(flags=(
            'awesome_flag',
            'flaggy_foo',
            'baz_bar',
        ))
    

    НО

    У батарейки есть существенный, на мой взгляд, недостаток — штатными средствами флаги невозможно выводить в понятном виде ни в админке, ни в собственных шаблонах. Для себя эту проблему я решил следующим образом:

    models.py:

    from django.db import models
    from django.utils.translation import ugettext_lazy as _
    from bitfield import BitField
    
    class MyModel(models.Model):
        
        FLAGS = (
            ('flag1', _('flag 1 description')),
            ('flag2', _('flag 2 description')),
            ('flag3', _('flag 3 description')),
        )
        
        flags = BitField([k for k, v in FLAGS])
    


    forms.py

    from django import forms
    from .models import MyModel
    class MyModelForm(forms.ModelForm):
    
        def _set_choices(self, field, choices):
            self.fields[field].widget.choices = choices
    
        def __init__(self, *args, **kwargs):
            super(MyModelForm, self).__init__(*args, **kwargs)
    
            self._set_choices('flags', MyModel.FLAGS)
    


    admin.py

    from django.contrib import admin
    from .forms import MyModelForm
    from .models import MyModel
    class MyModelAdmin(admin.ModelAdmin):
        form = MyModelForm
        
    admin.site.register(MyModel, MyModelAdmin)
    

    GitHub

    django-tagging


    Существует несколько реализаций тегов для Django, но я бы хотел обратить ваше внимание на ветку machinetags из этого репозитория.
    В этой реализации тегов добавлена возможность делить их между пространствами имён (namespaces) и, соответственно, для разных полей использовать разные наборы тегов.
    Так же есть возможность присваивать тегу дополнительные значения и хранить наборы из одинаковых тегов, но с разными значениями. Честно сказать, этому я пока применения не нашел.

    Мой форк на GitHub с некоторыми исправлениями.

    Но сам по себе модуль не поддерживает автодополнение — а это, согласитесь, очень полезная функция. Есть множество реализаций: раз, два, три — это только первые ссылки из гугла.
    Но ни один из них не поддерживает namespaces из описанной выше версии django-tagging, поэтому я взял на себя смелость устранить этот недостаток. Так и появился мой форк…

    django-tagging-autosuggest


    Никак не перепишу документацию, поэтому просто приведу пример использования:

    Приложение необходимо добавить в INSTALLED_APPS и в urls.py проекта:
    from django.conf.urls import patterns, include, url
    
    urlpatterns = patterns('',
        url(r'^tagging/', include('tagging_autosuggest.urls')),
    )
    


    И добавить нужные поля в модель:
    from django.db import models
    from tagging_autosuggest.fields import TagAutosuggestField
    
    class MyModel(models.Model):
        tags1 = TagAutosuggestField(namespace='ns1', max_length=300)
        tags2 = TagAutosuggestField(namespace='ns2', max_length=300)
    


    Результат:

    GitHub

    django-autocomplete-light


    Ещё одна батарейка, облегчающая работу со списками. Создаёт в админке удобные виджеты с автодополнением для полей типа CharField, ForeignKey, ManyToMany, а также для generic-связей (ForeignKey и M2M).

    Примеры использования можно посмотреть в тестовом проекте.

    А вот так выглядит GenericForeignKey в реальном проекте:

    GitHub
    Документация

    Мой скромный вклад в opensource: github.com/Yuego?tab=repositories

    Сообщения об ошибках, опечатках и т. п. по традиции принимаются в личку.
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 11

      +4
      Я для добавления тегов раньше тоже много пользовался всякими django-taggit и django-tagging, но уже давно начал использовать djorm-ext-pgarray. Как пример использования для тегов:
      from django.db import models
      from djorm_pgarray.fields import ArrayField
      from djorm_expressions.models import ExpressionManager
      
      class Post(models.Model):
          title = models.CharField(max_length=255)
          content = models.TextField()
          tags = ArrayField(dbtype="varchar(255)")
      
          objects = ExpressionManager()
      

      а потом:
      Post(title='Lorem Ipsum', content='Dolor sit amet', tags=['hello','world'])
      post.save()
      


      Удобное поле ввода с автокомплитом для этого сделал но без jquery-ui(как в вашем) а с использованием bootstrap tagmanager.
      Кому интересно, тут еще есть полезные плюшки типа djorm-ext-pool, djorm-ext-hstore, djorm-ext-pgfulltext, djorm-ext-pggeom, djorm-ext-pgbytea и другие.
        +2
        Ради одного этого комментария стоило писать статью :)

        Спасибо за наводку! Обязательно посмотрю в ближайшее время ваши djorm-ext.
        0
        А оно индексы поддерживает. Postgresql то понятно что GIN и GiST поддерживает, а само расширение?
          0
          Не поддерживает.
            0
            Уточню. Поддерживается обычный B-tree индекс по всему полю, но не GIN/GiST.
            0
            Тэги нам нужны для того, чтобы по ним можно было делать выборку необходимой информации, а не для того чтобы просто показать их внизу страницы. Проблема в том, что по элементам массива нельзя построить индекс, а значит выборки при большом объёме данных будут очень медленными. Вот цитата из документации:

            Arrays are not sets; searching for specific array elements can be a sign of database misdesign. Consider using a separate table with a row for each item that would be an array element. This will be easier to search, and is likely to scale better for a large number of elements.


            Решение, конечно, элегантное, но не производительное.
            +1
            Раз рассказываете про батарейки, хоть про каждую пару слов скажите и что они делают
              0
              Что именно Вам не понятно?
              0
              Интересно число — 5 :)
              Спасибо за пост, особенно за django-bitfield :)
                0
                Пожалуйста :)

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое