SlideShare a Scribd company logo
1 of 35
Download to read offline
Журнальная вёрстка
   Делаем “красиво” с Django

           Алексей Дубков
            alex@evid.ru


       MoscowDjango, 01/03/2012
CMS против

• Раньше верстали руками
• Сейчас копируют и вставляют
• Скучный “Текст”
• HTML-редактор не спасает
• Скудное оформление
Что хочется

• Перемешивать текст и графику
• Делать выноски, плашки
• Делать колонки
• Расставлять акценты
• Галерею, вот прямо сюда
И так...
В чём идея?

• Любой элемент — блок
• Блоки: текст + графика
• Сверху-вниз
• Слева-направо
• Блоки независимы друг от друга
Итак, блоки

• Они могут быть разных типов
• Как-то отсортированы
• Привязаны к Статье, Новости и т.д.
# blocks/models.py

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Block(models.Model):
    BLOCK_TYPES = (
        (11, u'T-01: Обычный текст'),
        (21, u'P-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)
# blocks/admin.py

from django.contrib import admin
from django.contrib.contenttypes.generic import
GenericStackedInline
from blocks.models import Block

class BlockInline(GenericStackedInline):
    model = Block
    extra = 0
    fieldsets = (
        (None, {
             'fields': (('block_type', 'sort',),
            'image', 'title', 'text',)
        }),
    )
Вывести блоки

• Выбираем блоки для статьи
• Склеиваем (CAN_COLLAPSE)
• Отдельный рендер для блока
• Склеиваем конечный HTML
# blocks/utils.py

from django.template import RequestContext, loader
from django.contrib.contenttypes.models import ContentType
from blocks.models import Block

def 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()
# 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
# 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
Шаблоны

• В простых шаблонах сразу выводятся
  переменные {{ title }}, {{ text }}...
• В склееных шаблонах нужен цикл
• {{ for item in blocks }}
Пример

• Делаем статьи
• Подключаем админку
• Блоки подключаем через inlines
• Делаем вывод
# articles/models.py

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=64)
    pub_date = models.DateField()
    blocks_html = models.TextField(blank=True)

    class Meta:
        ordering = ['-pub_date']
# articles/admin.py

from django.contrib import admin
from articles.models import Article
from blocks.admin import BlockInline

class ArticleAdmin(admin.ModelAdmin):
    save_on_top = True
    inlines = [BlockInline, ]
    list_display = ( 'title', 'pub_date',)

admin.site.register(Article, ArticleAdmin)
# articles/views.py

def 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))
Ньюансы

• Как хранить картинки
• Утомительная сортировка
• Производительность
# blocks/models.py

def image_upload(instance, filename):
    return "block/%s/%s" %
    (instance.content_object.block_image_path(),
    filename.lower())



# artiles/models.py

class Article(models.Model):
    ...
    def block_image_path(self):
        return "article/%d/%02d/%d" % (
               self.pub_date.year,
               self.pub_date.month,
               self.id)
$(document).ready(function(){
$('#block-block-content_type-object_id-group .add-row
a').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);

})
Скорость

• Производительность низкая
• Можно сохранять HTML
• Переопределив save_model в админке
  сохранять дважды
Минусы

• Сложно в обучении
• Можно “накакафонить”
• Подгонять контент под формат
Спасибо

More Related Content

What's hot

Basis.js – «под капотом»
Basis.js – «под капотом»Basis.js – «под капотом»
Basis.js – «под капотом»Roman Dvornov
 
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSКурсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSГлеб Тарасов
 
Сергей Бережной "Экзотическая шаблонизация, или как писать HTML для блоков"
Сергей Бережной "Экзотическая шаблонизация, или как писать HTML для блоков"Сергей Бережной "Экзотическая шаблонизация, или как писать HTML для блоков"
Сергей Бережной "Экзотическая шаблонизация, или как писать HTML для блоков"Yandex
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Яковенко Кирилл
 
Приложения для Windows Phone: как мы это делаем #codefest
Приложения для Windows Phone: как мы это делаем #codefestПриложения для Windows Phone: как мы это делаем #codefest
Приложения для Windows Phone: как мы это делаем #codefestActis Wunderman
 
MyBatis на практике
MyBatis на практикеMyBatis на практике
MyBatis на практикеVitebsk Miniq
 
Быстро о быстром
Быстро о быстромБыстро о быстром
Быстро о быстромRoman Dvornov
 
Tequila - язык для продвинутой генерации JSON
Tequila - язык для продвинутой генерации JSONTequila - язык для продвинутой генерации JSON
Tequila - язык для продвинутой генерации JSONIvan Nemytchenko
 
CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...
CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...
CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...CodeFest
 
TК°Conf. 10 проблем автоматизации UI и их решение с помощью JDI. Роман Иовлев.
TК°Conf. 10 проблем автоматизации UI и их решение с помощью JDI. Роман Иовлев.TК°Conf. 10 проблем автоматизации UI и их решение с помощью JDI. Роман Иовлев.
TК°Conf. 10 проблем автоматизации UI и их решение с помощью JDI. Роман Иовлев.TKConf
 
Ember.js ответ на почти все вопросы - java script frameworks day 2014
Ember.js   ответ на почти все вопросы - java script frameworks day 2014Ember.js   ответ на почти все вопросы - java script frameworks day 2014
Ember.js ответ на почти все вопросы - java script frameworks day 2014Andrey Listochkin
 
11 - Web-технологии. Работа с СУБД
11 - Web-технологии. Работа с СУБД11 - Web-технологии. Работа с СУБД
11 - Web-технологии. Работа с СУБДRoman Brovko
 
Внутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackВнутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackAlexey Ivanov
 

What's hot (15)

Basis.js – «под капотом»
Basis.js – «под капотом»Basis.js – «под капотом»
Basis.js – «под капотом»
 
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSКурсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
 
Сергей Бережной "Экзотическая шаблонизация, или как писать HTML для блоков"
Сергей Бережной "Экзотическая шаблонизация, или как писать HTML для блоков"Сергей Бережной "Экзотическая шаблонизация, или как писать HTML для блоков"
Сергей Бережной "Экзотическая шаблонизация, или как писать HTML для блоков"
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3
 
Приложения для Windows Phone: как мы это делаем #codefest
Приложения для Windows Phone: как мы это делаем #codefestПриложения для Windows Phone: как мы это делаем #codefest
Приложения для Windows Phone: как мы это делаем #codefest
 
MyBatis на практике
MyBatis на практикеMyBatis на практике
MyBatis на практике
 
Быстро о быстром
Быстро о быстромБыстро о быстром
Быстро о быстром
 
Tequila - язык для продвинутой генерации JSON
Tequila - язык для продвинутой генерации JSONTequila - язык для продвинутой генерации JSON
Tequila - язык для продвинутой генерации JSON
 
Лекция #7. Django ORM
Лекция #7. Django ORMЛекция #7. Django ORM
Лекция #7. Django ORM
 
CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...
CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...
CodeFest 2013. Никонов Г. — Как мы разрабатываем приложения для Windows Phone...
 
My batis
My batisMy batis
My batis
 
TК°Conf. 10 проблем автоматизации UI и их решение с помощью JDI. Роман Иовлев.
TК°Conf. 10 проблем автоматизации UI и их решение с помощью JDI. Роман Иовлев.TК°Conf. 10 проблем автоматизации UI и их решение с помощью JDI. Роман Иовлев.
TК°Conf. 10 проблем автоматизации UI и их решение с помощью JDI. Роман Иовлев.
 
Ember.js ответ на почти все вопросы - java script frameworks day 2014
Ember.js   ответ на почти все вопросы - java script frameworks day 2014Ember.js   ответ на почти все вопросы - java script frameworks day 2014
Ember.js ответ на почти все вопросы - java script frameworks day 2014
 
11 - Web-технологии. Работа с СУБД
11 - Web-технологии. Работа с СУБД11 - Web-технологии. Работа с СУБД
11 - Web-технологии. Работа с СУБД
 
Внутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackВнутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpack
 

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

12 - Web-технологии. Django модели
12 - Web-технологии. Django модели12 - Web-технологии. Django модели
12 - Web-технологии. Django моделиRoman Brovko
 
django cheBit'11
django cheBit'11django cheBit'11
django cheBit'11dva
 
Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...
Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...
Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...it-people
 
Разработка через тестирование в Python и Django #pyconru
Разработка через тестирование в Python и Django #pyconruРазработка через тестирование в Python и Django #pyconru
Разработка через тестирование в Python и Django #pyconruJetStyle
 
Pycon Russia 2013 - Разработка через тестирование в Python и Django
Pycon Russia 2013 - Разработка через тестирование в Python и DjangoPycon Russia 2013 - Разработка через тестирование в Python и Django
Pycon Russia 2013 - Разработка через тестирование в Python и DjangoIlya Shalyapin
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в DjangoMoscowDjango
 
Alex baumgertner bem_in_small_projects
Alex baumgertner bem_in_small_projectsAlex baumgertner bem_in_small_projects
Alex baumgertner bem_in_small_projectsAlexander Baumgertner
 
Web осень 2013 лекция 8
Web осень 2013 лекция 8Web осень 2013 лекция 8
Web осень 2013 лекция 8Technopark
 
Александр Баумгертнер — Преимущества БЭМ для небольших проектов и компаний
Александр Баумгертнер — Преимущества БЭМ для небольших проектов и компанийАлександр Баумгертнер — Преимущества БЭМ для небольших проектов и компаний
Александр Баумгертнер — Преимущества БЭМ для небольших проектов и компанийYandex
 
Web осень 2013 лекция 7
Web осень 2013 лекция 7Web осень 2013 лекция 7
Web осень 2013 лекция 7Technopark
 
Web весна 2012 лекция 7
Web весна 2012 лекция 7Web весна 2012 лекция 7
Web весна 2012 лекция 7Technopark
 
Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"
Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"
Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"Yandex
 
10 - Web-технологии. MVC фреймворки (продолжение)
10 - Web-технологии. MVC фреймворки (продолжение)10 - Web-технологии. MVC фреймворки (продолжение)
10 - Web-технологии. MVC фреймворки (продолжение)Roman Brovko
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному кодуVasiliy Deynega
 
Разработка и deploy Drupal сайтов с помощью Features.
Разработка и deploy Drupal сайтов с помощью Features.Разработка и deploy Drupal сайтов с помощью Features.
Разработка и deploy Drupal сайтов с помощью Features.Eugene Fidelin
 
По-настоящему ВИЗУАЛЬНОЕ построение лендинг-страниц на WP Gutenberg!
По-настоящему ВИЗУАЛЬНОЕ построение лендинг-страниц на WP Gutenberg!По-настоящему ВИЗУАЛЬНОЕ построение лендинг-страниц на WP Gutenberg!
По-настоящему ВИЗУАЛЬНОЕ построение лендинг-страниц на WP Gutenberg!Yevhen Kotelnytskyi
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Dima Dzuba
 

Similar to Журнальная вёрстка в Django (20)

12 - Web-технологии. Django модели
12 - Web-технологии. Django модели12 - Web-технологии. Django модели
12 - Web-технологии. Django модели
 
django cheBit'11
django cheBit'11django cheBit'11
django cheBit'11
 
Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...
Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...
Илья Шаляпин, Евгений Генералов: Разработка через тестирование в Python и Djn...
 
Разработка через тестирование в Python и Django #pyconru
Разработка через тестирование в Python и Django #pyconruРазработка через тестирование в Python и Django #pyconru
Разработка через тестирование в Python и Django #pyconru
 
Pycon Russia 2013 - Разработка через тестирование в Python и Django
Pycon Russia 2013 - Разработка через тестирование в Python и DjangoPycon Russia 2013 - Разработка через тестирование в Python и Django
Pycon Russia 2013 - Разработка через тестирование в Python и Django
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
 
Alex baumgertner bem_in_small_projects
Alex baumgertner bem_in_small_projectsAlex baumgertner bem_in_small_projects
Alex baumgertner bem_in_small_projects
 
Web осень 2013 лекция 8
Web осень 2013 лекция 8Web осень 2013 лекция 8
Web осень 2013 лекция 8
 
Александр Баумгертнер — Преимущества БЭМ для небольших проектов и компаний
Александр Баумгертнер — Преимущества БЭМ для небольших проектов и компанийАлександр Баумгертнер — Преимущества БЭМ для небольших проектов и компаний
Александр Баумгертнер — Преимущества БЭМ для небольших проектов и компаний
 
Web осень 2013 лекция 7
Web осень 2013 лекция 7Web осень 2013 лекция 7
Web осень 2013 лекция 7
 
Web весна 2012 лекция 7
Web весна 2012 лекция 7Web весна 2012 лекция 7
Web весна 2012 лекция 7
 
Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"
Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"
Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
10 - Web-технологии. MVC фреймворки (продолжение)
10 - Web-технологии. MVC фреймворки (продолжение)10 - Web-технологии. MVC фреймворки (продолжение)
10 - Web-технологии. MVC фреймворки (продолжение)
 
Yac2012
Yac2012Yac2012
Yac2012
 
БЭМ
БЭМБЭМ
БЭМ
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному коду
 
Разработка и deploy Drupal сайтов с помощью Features.
Разработка и deploy Drupal сайтов с помощью Features.Разработка и deploy Drupal сайтов с помощью Features.
Разработка и deploy Drupal сайтов с помощью Features.
 
По-настоящему ВИЗУАЛЬНОЕ построение лендинг-страниц на WP Gutenberg!
По-настоящему ВИЗУАЛЬНОЕ построение лендинг-страниц на WP Gutenberg!По-настоящему ВИЗУАЛЬНОЕ построение лендинг-страниц на WP Gutenberg!
По-настоящему ВИЗУАЛЬНОЕ построение лендинг-страниц на WP Gutenberg!
 
Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8. Объектно-ориентированное программирование. Лекция 7 и 8.
Объектно-ориентированное программирование. Лекция 7 и 8.
 

More from MoscowDjango

Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и DjangoMoscowDjango
 
Пример fuzzy testing для поиска URL в тексте
Пример fuzzy testing для поиска URL в текстеПример fuzzy testing для поиска URL в тексте
Пример fuzzy testing для поиска URL в текстеMoscowDjango
 
TDD или как я стараюсь писать код
TDD или как я стараюсь писать кодTDD или как я стараюсь писать код
TDD или как я стараюсь писать кодMoscowDjango
 
Cyclone + Eventsource (realtime push-сообщения)
Cyclone + Eventsource (realtime push-сообщения)Cyclone + Eventsource (realtime push-сообщения)
Cyclone + Eventsource (realtime push-сообщения)MoscowDjango
 
Django на Android
Django на AndroidDjango на Android
Django на AndroidMoscowDjango
 
Работа со статикой в Django
Работа со статикой в DjangoРабота со статикой в Django
Работа со статикой в DjangoMoscowDjango
 
Разработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoРазработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoMoscowDjango
 
Class Based Generic Views в Django
Class Based Generic Views в DjangoClass Based Generic Views в Django
Class Based Generic Views в DjangoMoscowDjango
 
Простой и удобный деплоймент проекта
Простой и удобный деплоймент проектаПростой и удобный деплоймент проекта
Простой и удобный деплоймент проектаMoscowDjango
 
Django South. Миграция баз данных.
Django South. Миграция баз данных.  Django South. Миграция баз данных.
Django South. Миграция баз данных. MoscowDjango
 

More from MoscowDjango (10)

Тестирование и Django
Тестирование и DjangoТестирование и Django
Тестирование и Django
 
Пример fuzzy testing для поиска URL в тексте
Пример fuzzy testing для поиска URL в текстеПример fuzzy testing для поиска URL в тексте
Пример fuzzy testing для поиска URL в тексте
 
TDD или как я стараюсь писать код
TDD или как я стараюсь писать кодTDD или как я стараюсь писать код
TDD или как я стараюсь писать код
 
Cyclone + Eventsource (realtime push-сообщения)
Cyclone + Eventsource (realtime push-сообщения)Cyclone + Eventsource (realtime push-сообщения)
Cyclone + Eventsource (realtime push-сообщения)
 
Django на Android
Django на AndroidDjango на Android
Django на Android
 
Работа со статикой в Django
Работа со статикой в DjangoРабота со статикой в Django
Работа со статикой в Django
 
Разработка расширяемых приложений на Django
Разработка расширяемых приложений на DjangoРазработка расширяемых приложений на Django
Разработка расширяемых приложений на Django
 
Class Based Generic Views в Django
Class Based Generic Views в DjangoClass Based Generic Views в Django
Class Based Generic Views в Django
 
Простой и удобный деплоймент проекта
Простой и удобный деплоймент проектаПростой и удобный деплоймент проекта
Простой и удобный деплоймент проекта
 
Django South. Миграция баз данных.
Django South. Миграция баз данных.  Django South. Миграция баз данных.
Django South. Миграция баз данных.
 

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

  • 1. Журнальная вёрстка Делаем “красиво” с Django Алексей Дубков alex@evid.ru MoscowDjango, 01/03/2012
  • 2. CMS против • Раньше верстали руками • Сейчас копируют и вставляют • Скучный “Текст” • HTML-редактор не спасает • Скудное оформление
  • 3.
  • 4.
  • 5. Что хочется • Перемешивать текст и графику • Делать выноски, плашки • Делать колонки • Расставлять акценты • Галерею, вот прямо сюда
  • 6.
  • 8.
  • 9.
  • 10.
  • 11. В чём идея? • Любой элемент — блок • Блоки: текст + графика • Сверху-вниз • Слева-направо • Блоки независимы друг от друга
  • 12.
  • 13.
  • 14. Итак, блоки • Они могут быть разных типов • Как-то отсортированы • Привязаны к Статье, Новости и т.д.
  • 15. # blocks/models.py from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic class Block(models.Model): BLOCK_TYPES = ( (11, u'T-01: Обычный текст'), (21, u'P-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)
  • 16. # blocks/admin.py from django.contrib import admin from django.contrib.contenttypes.generic import GenericStackedInline from blocks.models import Block class BlockInline(GenericStackedInline): model = Block extra = 0 fieldsets = ( (None, { 'fields': (('block_type', 'sort',), 'image', 'title', 'text',) }), )
  • 17. Вывести блоки • Выбираем блоки для статьи • Склеиваем (CAN_COLLAPSE) • Отдельный рендер для блока • Склеиваем конечный HTML
  • 18. # blocks/utils.py from django.template import RequestContext, loader from django.contrib.contenttypes.models import ContentType from blocks.models import Block def 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()
  • 19. # 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
  • 20. # 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
  • 21. Шаблоны • В простых шаблонах сразу выводятся переменные {{ title }}, {{ text }}... • В склееных шаблонах нужен цикл • {{ for item in blocks }}
  • 22. Пример • Делаем статьи • Подключаем админку • Блоки подключаем через inlines • Делаем вывод
  • 23. # articles/models.py from django.db import models class Article(models.Model): title = models.CharField(max_length=64) pub_date = models.DateField() blocks_html = models.TextField(blank=True) class Meta: ordering = ['-pub_date']
  • 24. # articles/admin.py from django.contrib import admin from articles.models import Article from blocks.admin import BlockInline class ArticleAdmin(admin.ModelAdmin): save_on_top = True inlines = [BlockInline, ] list_display = ( 'title', 'pub_date',) admin.site.register(Article, ArticleAdmin)
  • 25.
  • 26. # articles/views.py def 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))
  • 27.
  • 28. Ньюансы • Как хранить картинки • Утомительная сортировка • Производительность
  • 29. # blocks/models.py def image_upload(instance, filename): return "block/%s/%s" % (instance.content_object.block_image_path(), filename.lower()) # artiles/models.py class Article(models.Model): ... def block_image_path(self): return "article/%d/%02d/%d" % ( self.pub_date.year, self.pub_date.month, self.id)
  • 30. $(document).ready(function(){ $('#block-block-content_type-object_id-group .add-row a').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); })
  • 31. Скорость • Производительность низкая • Можно сохранять HTML • Переопределив save_model в админке сохранять дважды
  • 32. Минусы • Сложно в обучении • Можно “накакафонить” • Подгонять контент под формат
  • 33.
  • 34.