More Related Content Similar to Журнальная вёрстка в Django Similar to Журнальная вёрстка в Django (20) More from MoscowDjango (10) Журнальная вёрстка в Django1. Журнальная вёрстка
Делаем “красиво” с Django
Алексей Дубков
alex@evid.ru
MoscowDjango, 01/03/2012
2. CMS против
• Раньше верстали руками
• Сейчас копируют и вставляют
• Скучный “Текст”
• HTML-редактор не спасает
• Скудное оформление
5. Что хочется
• Перемешивать текст и графику
• Делать выноски, плашки
• Делать колонки
• Расставлять акценты
• Галерею, вот прямо сюда
11. В чём идея?
• Любой элемент — блок
• Блоки: текст + графика
• Сверху-вниз
• Слева-направо
• Блоки независимы друг от друга
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 }}
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)
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))
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)