Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Журнальная вёрстка   Делаем “красиво” с Django           Алексей Дубков            alex@evid.ru       MoscowDjango, 01/03/...
CMS против• Раньше верстали руками• Сейчас копируют и вставляют• Скучный “Текст”• HTML-редактор не спасает• Скудное оформл...
Что хочется• Перемешивать текст и графику• Делать выноски, плашки• Делать колонки• Расставлять акценты• Галерею, вот прямо...
И так...
В чём идея?• Любой элемент — блок• Блоки: текст + графика• Сверху-вниз• Слева-направо• Блоки независимы друг от друга
Итак, блоки• Они могут быть разных типов• Как-то отсортированы• Привязаны к Статье, Новости и т.д.
# blocks/models.pyfrom django.db import modelsfrom django.contrib.contenttypes.models import ContentTypefrom django.contri...
# blocks/admin.pyfrom django.contrib import adminfrom django.contrib.contenttypes.generic importGenericStackedInlinefrom b...
Вывести блоки• Выбираем блоки для статьи• Склеиваем (CAN_COLLAPSE)• Отдельный рендер для блока• Склеиваем конечный HTML
# blocks/utils.pyfrom django.template import RequestContext, loaderfrom django.contrib.contenttypes.models import ContentT...
# blocks/utils.py    ...    bl = []     # blocks tuple (type, data)    if blocks_count:        it = 0        i = 0        ...
# blocks/utils.py    ...    html =    # result html    if blocks_count:        for (type, item) in bl:            t_name =...
Шаблоны• В простых шаблонах сразу выводятся  переменные {{ title }}, {{ text }}...• В склееных шаблонах нужен цикл• {{ for...
Пример• Делаем статьи• Подключаем админку• Блоки подключаем через inlines• Делаем вывод
# articles/models.pyfrom django.db import modelsclass Article(models.Model):    title = models.CharField(max_length=64)   ...
# articles/admin.pyfrom django.contrib import adminfrom articles.models import Articlefrom blocks.admin import BlockInline...
# articles/views.pydef articles_one(request, id):    obj = get_object_or_404(Article, id=id)    blocks_html = get_blocks_h...
Ньюансы• Как хранить картинки• Утомительная сортировка• Производительность
# blocks/models.pydef image_upload(instance, filename):    return "block/%s/%s" %    (instance.content_object.block_image_...
$(document).ready(function(){$(#block-block-content_type-object_id-group .add-rowa).click(function(){var totalBlocks=$(#id...
Скорость• Производительность низкая• Можно сохранять HTML• Переопределив save_model в админке  сохранять дважды
Минусы• Сложно в обучении• Можно “накакафонить”• Подгонять контент под формат
Спасибо
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Журнальная вёрстка в Django
Upcoming SlideShare
Loading in …5
×

Журнальная вёрстка в Django

4,136 views

Published on

Published in: Technology
  • Be the first to comment

Журнальная вёрстка в Django

  1. 1. Журнальная вёрстка Делаем “красиво” с Django Алексей Дубков alex@evid.ru MoscowDjango, 01/03/2012
  2. 2. CMS против• Раньше верстали руками• Сейчас копируют и вставляют• Скучный “Текст”• HTML-редактор не спасает• Скудное оформление
  3. 3. Что хочется• Перемешивать текст и графику• Делать выноски, плашки• Делать колонки• Расставлять акценты• Галерею, вот прямо сюда
  4. 4. И так...
  5. 5. В чём идея?• Любой элемент — блок• Блоки: текст + графика• Сверху-вниз• Слева-направо• Блоки независимы друг от друга
  6. 6. Итак, блоки• Они могут быть разных типов• Как-то отсортированы• Привязаны к Статье, Новости и т.д.
  7. 7. # blocks/models.pyfrom django.db import modelsfrom django.contrib.contenttypes.models import ContentTypefrom django.contrib.contenttypes import genericclass Block(models.Model): BLOCK_TYPES = ( (11, uT-01: Обычный текст), (21, uP-01: Картинки 250x в 3 колонки),) CAN_COLLAPSE = (21,) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( content_type, object_id) block_type = models.IntegerField(choices=BLOCK_TYPES) sort = models.IntegerField(default=20) image = models.ImageField(blank=True) title = models.CharField(max_length=255, blank=True) text = models.TextField(blank=True)
  8. 8. # blocks/admin.pyfrom django.contrib import adminfrom django.contrib.contenttypes.generic importGenericStackedInlinefrom blocks.models import Blockclass BlockInline(GenericStackedInline): model = Block extra = 0 fieldsets = ( (None, { fields: ((block_type, sort,), image, title, text,) }), )
  9. 9. Вывести блоки• Выбираем блоки для статьи• Склеиваем (CAN_COLLAPSE)• Отдельный рендер для блока• Склеиваем конечный HTML
  10. 10. # blocks/utils.pyfrom django.template import RequestContext, loaderfrom django.contrib.contenttypes.models import ContentTypefrom blocks.models import Blockdef get_blocks_html(request, obj): content_type = ContentType.objects.get( model=obj.__class__.__name__) blocks = Block.objects.filter( content_type=content_type, object_id=obj.id).order_by(sort) blocks_count = blocks.count()
  11. 11. # blocks/utils.py ... bl = [] # blocks tuple (type, data) if blocks_count: it = 0 i = 0 while i < blocks_count: type = blocks[i].block_type if type in Block.CAN_COLLAPSE: result = [] it = i for j in blocks[i:]: if j.block_type == type: result.append(j) it += 1 else: break bl.append([type, {blocks:result}]) i = it - 1 else: bl.append([type, blocks[i].__dict__]) i += 1
  12. 12. # blocks/utils.py ... html = # result html if blocks_count: for (type, item) in bl: t_name = "blocks/block-%s.html" % type t = loader.get_template(t_name) render = t.render( RequestContext(request, item)) html += render return html
  13. 13. Шаблоны• В простых шаблонах сразу выводятся переменные {{ title }}, {{ text }}...• В склееных шаблонах нужен цикл• {{ for item in blocks }}
  14. 14. Пример• Делаем статьи• Подключаем админку• Блоки подключаем через inlines• Делаем вывод
  15. 15. # articles/models.pyfrom django.db import modelsclass Article(models.Model): title = models.CharField(max_length=64) pub_date = models.DateField() blocks_html = models.TextField(blank=True) class Meta: ordering = [-pub_date]
  16. 16. # articles/admin.pyfrom django.contrib import adminfrom articles.models import Articlefrom blocks.admin import BlockInlineclass ArticleAdmin(admin.ModelAdmin): save_on_top = True inlines = [BlockInline, ] list_display = ( title, pub_date,)admin.site.register(Article, ArticleAdmin)
  17. 17. # articles/views.pydef articles_one(request, id): obj = get_object_or_404(Article, id=id) blocks_html = get_blocks_html(request, obj) return render_to_response( articles/articles_one.html, {obj: obj,blocks_html: blocks_html,}, context_instance=RequestContext(request))
  18. 18. Ньюансы• Как хранить картинки• Утомительная сортировка• Производительность
  19. 19. # blocks/models.pydef image_upload(instance, filename): return "block/%s/%s" % (instance.content_object.block_image_path(), filename.lower())# artiles/models.pyclass Article(models.Model): ... def block_image_path(self): return "article/%d/%02d/%d" % ( self.pub_date.year, self.pub_date.month, self.id)
  20. 20. $(document).ready(function(){$(#block-block-content_type-object_id-group .add-rowa).click(function(){var totalBlocks=$(#id_block-block-content_type-object_id-TOTAL_FORMS).val();var sortFieldId="#id_block-block-content_type-object_id-"+parseInt(totalBlocks-2)+"-sort";var newSortFieldId="#id_block-block-content_type-object_id-"+parseInt(totalBlocks-1)+"-sort";var lastSortVal=$(sortFieldId).val();var newSortVal=parseInt(lastSortVal)+10;$(newSortFieldId).val(newSortVal);})
  21. 21. Скорость• Производительность низкая• Можно сохранять HTML• Переопределив save_model в админке сохранять дважды
  22. 22. Минусы• Сложно в обучении• Можно “накакафонить”• Подгонять контент под формат
  23. 23. Спасибо

×