SlideShare ist ein Scribd-Unternehmen logo
1 von 50
Downloaden Sie, um offline zu lesen
DJANGO MEETUP - SKILLS MATTER
DJANGO CMS
BEST PRACTICES
by
Iacopo Spalletti
@yakkys
WHO AM I?
Founder and Lead developer @NephilaIt
django CMS core developer 
django CMS installer author
DJANGO CMS
BEST PRACTICES
django CMS applications are just Django applications
With a twist
DJANGO CMS BEST PRACTICES
WHY?
Writing Django applications is easy
Writing effective and clean Django applications
requires some effort
DJANGO CMS BEST PRACTICES
WHAT'S THAT?
Guidelines being developed by the core team
Community feedback
My experience
DJANGO CMS BEST PRACTICES
WHAT FOR?
Providing:
DRY
Reusability
Tight integration with on-site and off-site services (full-
text search, social networks ...)
Principle of least surprise
DJANGO CMS BEST PRACTICES
CAVEATS
Nowhere near comprehensive
Still in flux
Task for 2015: Define the best practices Code hooks
into django CMS core
DJANGO CMS BEST PRACTICES
YET ANOTHER BLOG
EXAMPLE
Standard blog features
Pluggable onto multiple pages with different
configurations
Integration with social networks
Integration with full-text search
DJANGO CMS BEST PRACTICES
THE BASICS
always define cms_app.py
never plug the application in urlconf directly
prefer translatable models using django-parler
use tests :)
follow code conventions
(don't follow this talk code style)
DJANGO CMS BEST PRACTICES
THE DETAILS
Templates inheritance
Namespace configuration
django CMS Frontend editor
django CMS Toolbar
Meta tags
Haystack integration
DJANGO CMS BEST PRACTICES
LET'S START
We will use djangocms_blog as a base
List of posts
Post detail view
Tags
Categories
Comments
...
DJANGO CMS BEST PRACTICES
TEMPLATES INHERITANCE
Use django CMS page templates!
{% extends CMS_TEMPLATE %}
{% block meta %}
    {%  if meta %}
        {% include "meta_mixin/meta.html" %}
    {% endif %}
{% endblock meta %}
{% block content %}
<div class="app app­blog span8">
    {% block content_blog %}{% endblock %}
</div>
{% endblock content %}
DJANGO CMS BEST PRACTICES
TEMPLATE RULES
Extends CMS_TEMPLATEvariable
Define a conventional blockeach application
should redefine
We'll see the meta_mixin/meta.htmlinclude
later
DJANGO CMS BEST PRACTICES
TEMPLATES LAYOUT
Divide application template from plugin ones
DJANGO CMS BEST PRACTICES
TEMPLATES LAYOUT
Use includes to share the common code​
<div class="plugin plugin­blog"><div class="blog­latest­entries">
    {% for post in posts_list %}
        {% include "djangocms_blog/includes/blog_item.html" with post=post
    {% empty %}
        <p class="blog­empty">{% trans "No article found." %}</p>
    {% endfor %}
    </div></div>
DJANGO CMS BEST PRACTICES
NAMESPACE SUPPORT
Django built in support:
from django.conf.urls import include, patterns, url
urlpatterns = patterns('',
    url(r'^blog/', include('djangocms_blog.urls', namespace='blog1'
    url(r'^other­blog/', include('djangocms_blog.urls', namespace='blog2'
)
my_url = reverse('djangocms_blog:index', current_app='blog1')
my_url = reverse('djangocms_blog:index', current_app=request.resolver_matc
DJANGO CMS BEST PRACTICES
DJANGO CMS SUPPORT
django CMS just uses Django's own
class BlogApp(CMSApp):
    name = _('Blog')
    urls = ['djangocms_blog.urls']
    app_name = 'djangocms_blog'
apphook_pool.register(BlogApp)
DJANGO CMS BEST PRACTICES
NEW IN 3.1!
Enter aldryn-apphooks-config
class BlogConfig(TranslatableModel, AppHookConfig):
    paginate_by = models.PositiveIntegerField(
        _('Paginate size'),
        blank=False,
        default=5,
    )
    ...
class NewsBlogConfigForm(AppDataForm):
    pass
setup_config(NewsBlogConfigForm, NewsBlogConfig)
DJANGO CMS BEST PRACTICES
ALDRYN-APPHOOKS-
CONFIG
Integrated with django CMS namespace instance
creation
Definition of per-namespace instance options
Tied to each model instance
class Post(ModelMeta, TranslatableModel):
   ...
   app_config = models.ForeignKey(BlogConfig,
        verbose_name=_('app. config'))
DJANGO CMS BEST PRACTICES
IN VIEWS
AppConfigMixin:
sets up the namespace support
retrieves the current configuration
class PostListView(AppConfigMixin, ViewUrlMixin, ListView):
    model = Post
    context_object_name = 'post_list'
    template_name = 'djangocms_blog/post_list.html'
    view_url_name = 'djangocms_blog:posts­latest'
    def get_paginate_by(self, queryset):
        return self.app_config.paginate_by
DJANGO CMS BEST PRACTICES
IN THE ADMIN
Use ModelAppHookConfigto get options values
(e.g. in admin forms)
class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin
                PlaceholderAdminMixin, TranslatableAdmin, ModelAppHookConf
                admin.ModelAdmin):
    app_config_values = {
        'default_published': 'publish'
    }
DJANGO CMS BEST PRACTICES
IN THE TEMPLATE
Access the related namespace instance config through
the current model
{% if post.app_config.use_placeholder %}
    <div class="blog­content">{% render_placeholder post.content %}
{% else %}
    <div class="blog­content">{% render_model post "post_text" "post_text"
{% endif %}
DJANGO CMS BEST PRACTICES
DJANGO CMS FRONTEND
EDITOR
DJANGO CMS BEST PRACTICES
DJANGO CMS FRONTEND
EDITOR
Base for plugins behaviour
A wrapper around standard Django admin
Available for all Django applications
DJANGO CMS BEST PRACTICES
USE IT!
Add FrontendEditableAdminMixin
class PostAdmin(FrontendEditableAdminMixin,
                PlaceholderAdminMixin, TranslatableAdmin,
                admin.ModelAdmin):
    model = Post
    frontend_editable_fields = ('title', 'abstract', 'post_text')
    ...
DJANGO CMS BEST PRACTICES
USE IT!
Add template magic
<h2>{% render_model post "title" %}</h2>
<div class="blog­content">
{% render_model post "post_text" "post_text" %}
</div>
Edit the whole post
Or just some fields
DJANGO CMS BEST PRACTICES
USE IT!
DJANGO CMS BEST PRACTICES
POWER TO THE USERS
Toolbar is the main django CMS UI
DJANGO CMS BEST PRACTICES
POWER TO THE USERS
Available to all Django applications
DJANGO CMS BEST PRACTICES
HOW TO IMPLEMENT IT
Toolbar is very rich and powerful
I'll just show the basics
Check documentation for details
http://django-cms.rtfd.org/en/develop/how_to/toolbar.html
DJANGO CMS BEST PRACTICES
HOW TO IMPLEMENT IT
Create cms_toolbar.py
Define the links to the admin views
@toolbar_pool.register
class BlogToolbar(CMSToolbar):
    watch_models = [Post]
    def populate(self):
        if not self.is_current_app:
            return
        admin_menu = self.toolbar.get_or_create_menu(
             'djangocms_blog', _('Blog'))
        url = reverse('admin:djangocms_blog_post_changelist')
        admin_menu.add_modal_item(_('Post list'), url=url)
        url = reverse('admin:djangocms_blog_post_add')
        admin_menu.add_modal_item(_('Add post'), url=url)
 
DJANGO CMS BEST PRACTICES
HOW TO IMPLEMENT IT
Add contextual-aware links
current_post = getattr(self.request, BLOG_CURRENT_POST_IDENTIFIER)
if current_post:
    admin_menu.add_modal_item(_('Edit Post'),
        reverse(
            'admin:djangocms_blog_post_change',
                args=(current_post.pk,)
        ), active=True)
class PostDetailView(TranslatableSlugMixin, BaseBlogView, DetailView)
    model = Post
    def get_context_data(self, **kwargs):
        context = super(PostDetailView, self).get_context_data(**kwargs)
        setattr(self.request, BLOG_CURRENT_POST_IDENTIFIER, self.get_objec
        return context
DJANGO CMS BEST PRACTICES
SOME NOTES
Redirect browser to current post upon edit
class BlogToolbar(CMSToolbar):
    watch_models = [Post]
Hide the application toolbar item when outside the
application URLs
def populate(self):
    if not self.is_current_app:
        return
DJANGO CMS BEST PRACTICES
SHARE THE PASSION!
Content is dumb without metadata
schema.org
OpenGraph
...
Metadata defines the meaning of the content
DJANGO CMS BEST PRACTICES
DJANGO CMS HAS GOT
THAT COVERED!
django-meta/ django-meta-mixin
Django applications to format document metadata:
title
author
image
...
DJANGO CMS BEST PRACTICES
AN EXAMPLE
Define an attribute that maps metadata properties to
attribute/function/callable
Include a template
...
That's all
 
DJANGO CMS BEST PRACTICES
THE MODEL
_metadata = {
    'title': 'get_title',
    'description': 'get_description',
    'og_description': 'get_description',
    'image': 'get_image_full_url',
    'object_type': get_setting('TYPE'),
    ....
}
def get_title(self):
    title = self.safe_translation_getter('meta_title')
    if not title:
        title = self.safe_translation_getter('title')
    return title.strip()
def get_image_full_url(self):
DJANGO CMS BEST PRACTICES
THE VIEW
as_meta()method does the magic
def get_context_data(self, **kwargs):
    context = super(MyView, self).get_context_data(**kwargs)
    context['meta'] = self.get_object().as_meta()
    return context
DJANGO CMS BEST PRACTICES
THE TEMPLATE
Templates are even easier
<head>
    ...
    {% include "meta_mixin/meta.html" %}
    ...
</head>
DJANGO CMS BEST PRACTICES
IT'S DONE
<meta property="og:title" content="L'evento Djangobeer a Firenze, organizz
<meta property="og:url" content="http://www.nephila.it/it/blog/2014/09/18/
<meta property="og:description" content="La prima Djangobeer a Firenze: co
<meta property="og:image" content="http://www.nephila.it/media/filer_publi
<meta property="og:type" content="Article">
<meta property="article:published_time" content="2014­09­18 18:03:20"
<meta property="article:modified_time" content="2014­12­24 11:44:15.769410
<meta name="twitter:domain" content="www.nephila.it">
<meta name="twitter:card" content="Summary">
<meta name="twitter:title" content="L'evento Djangobeer a Firenze, organiz
<meta name="twitter:url" content="http://www.nephila.it/it/blog/2014/09/18
<meta name="twitter:description" content="La prima Djangobeer a Firenze: c
<meta name="twitter:image:src" content="http://www.nephila.it/media/filer_
<meta name="twitter:creator" content="@NephilaIt">
<meta name="twitter:site" content="@nephilait">
<link rel="author" href="https://plus.google.com/+NephilaIt"/>
DJANGO CMS BEST PRACTICES
THE IMPORTANCE OF BEING
INDEXED
What if I want to make my content indexable?
aldryn_search to the rescue
Easier binding between Haystack and your models
Knows a few things of django CMS
DJANGO CMS BEST PRACTICES
HOW TO CREATE THE INDEX
search_indexes.py
class PostIndex(get_index_base()):
    def get_title(self, obj):
        return obj.get_title()
    def index_queryset(self, using=None):
        self._get_backend(using)
        language = self.get_current_language(using)
        filter_kwargs = self.get_index_kwargs(language)
        qs = self.get_index_queryset(language)
        if filter_kwargs:
            return qs.translated(language, **filter_kwargs)
        return qs
    def get_index_queryset(self, language):
        return self.get_model().objects.active_translations(
            language_code=language).filter(app_config__search_indexed=
DJANGO CMS BEST PRACTICES
HOW TO CREATE THE INDEX
#2
def get_search_data(self, language=None, request=None):
        """
        Provides an index for use with Haystack, or, for populating
        Article.translations.search_data.
        """
        if not self.pk:
            return ''
        if language is None:
            language = get_language()
        if request is None:
            request = get_request(language=language)
        description = self.safe_translation_getter('lead_in')
        text_bits = [strip_tags(description)]
        for category in self.categories.all():
            text_bits.append(
                force_unicode(category.safe_translation_getter('name'
DJANGO CMS BEST PRACTICES
CONFUSED?
It may looks complex at first
Have a look at other examples
aldryn-newsblog
djangocms-blog
aldryn-events
 
DJANGO CMS BEST PRACTICES
TO BE CONTINUED...
There's more to come!
Content versioning support
Managing draft/live copy version of objects
Your suggestions
A detailed white paper in the next months
GRAZIE!
QUESTIONS?

Weitere ähnliche Inhalte

Was ist angesagt?

La conduite du changement dans une transformation SAFe - Retour d'expérience ...
La conduite du changement dans une transformation SAFe - Retour d'expérience ...La conduite du changement dans une transformation SAFe - Retour d'expérience ...
La conduite du changement dans une transformation SAFe - Retour d'expérience ...
Agile En Seine
 
Você sabe a diferença entre os níveis profissionais
Você sabe a diferença entre os níveis profissionaisVocê sabe a diferença entre os níveis profissionais
Você sabe a diferença entre os níveis profissionais
ampla engenharia
 

Was ist angesagt? (20)

Técnicas de Fatiamento - Product Tank - Renan Dias.pdf
Técnicas de Fatiamento - Product Tank - Renan Dias.pdfTécnicas de Fatiamento - Product Tank - Renan Dias.pdf
Técnicas de Fatiamento - Product Tank - Renan Dias.pdf
 
Guia do Papel e Responsabilidade do Scrum Master
Guia do Papel e Responsabilidade do Scrum MasterGuia do Papel e Responsabilidade do Scrum Master
Guia do Papel e Responsabilidade do Scrum Master
 
Gestao de Projeto com gráfico burndown
Gestao de Projeto com gráfico burndownGestao de Projeto com gráfico burndown
Gestao de Projeto com gráfico burndown
 
Selling Agile
Selling AgileSelling Agile
Selling Agile
 
Scrum Process
Scrum ProcessScrum Process
Scrum Process
 
Scrum em 15 minutos
Scrum em 15 minutosScrum em 15 minutos
Scrum em 15 minutos
 
La conduite du changement dans une transformation SAFe - Retour d'expérience ...
La conduite du changement dans une transformation SAFe - Retour d'expérience ...La conduite du changement dans une transformation SAFe - Retour d'expérience ...
La conduite du changement dans une transformation SAFe - Retour d'expérience ...
 
El Auténtico Scrum Master
El Auténtico Scrum MasterEl Auténtico Scrum Master
El Auténtico Scrum Master
 
Manual empreendedorismo e competências empreendedoras
Manual empreendedorismo e competências empreendedorasManual empreendedorismo e competências empreendedoras
Manual empreendedorismo e competências empreendedoras
 
Treinamento Agile Coach
Treinamento Agile CoachTreinamento Agile Coach
Treinamento Agile Coach
 
Mindset Ágil
Mindset ÁgilMindset Ágil
Mindset Ágil
 
Você sabe a diferença entre os níveis profissionais
Você sabe a diferença entre os níveis profissionaisVocê sabe a diferença entre os níveis profissionais
Você sabe a diferença entre os níveis profissionais
 
How to Become an Indispensable Scrum Master
How to Become an Indispensable Scrum MasterHow to Become an Indispensable Scrum Master
How to Become an Indispensable Scrum Master
 
Kanban - Agilidade Fora da TI - Case Riachuelo
Kanban - Agilidade Fora da TI - Case RiachueloKanban - Agilidade Fora da TI - Case Riachuelo
Kanban - Agilidade Fora da TI - Case Riachuelo
 
Desenvolvimento de Negócios Inovadores
Desenvolvimento de Negócios InovadoresDesenvolvimento de Negócios Inovadores
Desenvolvimento de Negócios Inovadores
 
Lean Inception & PBB: Cómo integrar ambas técnicas para construir el Backlog ...
Lean Inception & PBB: Cómo integrar ambas técnicas para construir el Backlog ...Lean Inception & PBB: Cómo integrar ambas técnicas para construir el Backlog ...
Lean Inception & PBB: Cómo integrar ambas técnicas para construir el Backlog ...
 
O que são mindsets
O que são mindsetsO que são mindsets
O que são mindsets
 
Treinamento de Scrum
Treinamento de ScrumTreinamento de Scrum
Treinamento de Scrum
 
Inteligência emocional na gestão de resultados
Inteligência emocional na gestão de resultadosInteligência emocional na gestão de resultados
Inteligência emocional na gestão de resultados
 
Certified Scrum Product Owner: class desk, posters and photos
Certified Scrum Product Owner: class desk, posters and photosCertified Scrum Product Owner: class desk, posters and photos
Certified Scrum Product Owner: class desk, posters and photos
 

Ähnlich wie Django cms best practices

Write your first WordPress plugin
Write your first WordPress pluginWrite your first WordPress plugin
Write your first WordPress plugin
Anthony Montalbano
 
What’S New In Newforms Admin
What’S New In Newforms AdminWhat’S New In Newforms Admin
What’S New In Newforms Admin
DjangoCon2008
 
A Basic Django Introduction
A Basic Django IntroductionA Basic Django Introduction
A Basic Django Introduction
Ganga Ram
 

Ähnlich wie Django cms best practices (20)

Treinamento django
Treinamento djangoTreinamento django
Treinamento django
 
Web development with django - Basics Presentation
Web development with django - Basics PresentationWeb development with django - Basics Presentation
Web development with django - Basics Presentation
 
بررسی چارچوب جنگو
بررسی چارچوب جنگوبررسی چارچوب جنگو
بررسی چارچوب جنگو
 
Django tutorial
Django tutorialDjango tutorial
Django tutorial
 
DJango
DJangoDJango
DJango
 
Django
DjangoDjango
Django
 
Write your first WordPress plugin
Write your first WordPress pluginWrite your first WordPress plugin
Write your first WordPress plugin
 
learnpythondjangochapteroneintroduction.pptx
learnpythondjangochapteroneintroduction.pptxlearnpythondjangochapteroneintroduction.pptx
learnpythondjangochapteroneintroduction.pptx
 
Reusable Apps
Reusable AppsReusable Apps
Reusable Apps
 
Hands on django part 1
Hands on django part 1Hands on django part 1
Hands on django part 1
 
Django - basics
Django - basicsDjango - basics
Django - basics
 
What’S New In Newforms Admin
What’S New In Newforms AdminWhat’S New In Newforms Admin
What’S New In Newforms Admin
 
Mini Curso Django Ii Congresso Academico Ces
Mini Curso Django Ii Congresso Academico CesMini Curso Django Ii Congresso Academico Ces
Mini Curso Django Ii Congresso Academico Ces
 
React django
React djangoReact django
React django
 
How to Webpack your Django!
How to Webpack your Django!How to Webpack your Django!
How to Webpack your Django!
 
Django by rj
Django by rjDjango by rj
Django by rj
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
A Basic Django Introduction
A Basic Django IntroductionA Basic Django Introduction
A Basic Django Introduction
 
An Introduction to Django Web Framework
An Introduction to Django Web FrameworkAn Introduction to Django Web Framework
An Introduction to Django Web Framework
 
Django Frequently Asked Interview Questions
Django Frequently Asked Interview QuestionsDjango Frequently Asked Interview Questions
Django Frequently Asked Interview Questions
 

Kürzlich hochgeladen

Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
mbmh111980
 

Kürzlich hochgeladen (20)

OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024
 
Lessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdfLessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdf
 
Microsoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMicrosoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdf
 
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAOpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
 
Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024
 
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdfThe Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
How to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabberHow to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabber
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
 
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024
 
SQL Injection Introduction and Prevention
SQL Injection Introduction and PreventionSQL Injection Introduction and Prevention
SQL Injection Introduction and Prevention
 
AI Hackathon.pptx
AI                        Hackathon.pptxAI                        Hackathon.pptx
AI Hackathon.pptx
 
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdfMicrosoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
 
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
 
Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024
 
IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024
 
5 Reasons Driving Warehouse Management Systems Demand
5 Reasons Driving Warehouse Management Systems Demand5 Reasons Driving Warehouse Management Systems Demand
5 Reasons Driving Warehouse Management Systems Demand
 
10 Essential Software Testing Tools You Need to Know About.pdf
10 Essential Software Testing Tools You Need to Know About.pdf10 Essential Software Testing Tools You Need to Know About.pdf
10 Essential Software Testing Tools You Need to Know About.pdf
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 

Django cms best practices

  • 1. DJANGO MEETUP - SKILLS MATTER DJANGO CMS BEST PRACTICES by Iacopo Spalletti @yakkys
  • 2. WHO AM I? Founder and Lead developer @NephilaIt django CMS core developer  django CMS installer author
  • 3. DJANGO CMS BEST PRACTICES django CMS applications are just Django applications With a twist
  • 4. DJANGO CMS BEST PRACTICES WHY? Writing Django applications is easy Writing effective and clean Django applications requires some effort
  • 5. DJANGO CMS BEST PRACTICES WHAT'S THAT? Guidelines being developed by the core team Community feedback My experience
  • 6. DJANGO CMS BEST PRACTICES WHAT FOR? Providing: DRY Reusability Tight integration with on-site and off-site services (full- text search, social networks ...) Principle of least surprise
  • 7. DJANGO CMS BEST PRACTICES CAVEATS Nowhere near comprehensive Still in flux Task for 2015: Define the best practices Code hooks into django CMS core
  • 8. DJANGO CMS BEST PRACTICES YET ANOTHER BLOG EXAMPLE Standard blog features Pluggable onto multiple pages with different configurations Integration with social networks Integration with full-text search
  • 9. DJANGO CMS BEST PRACTICES THE BASICS always define cms_app.py never plug the application in urlconf directly prefer translatable models using django-parler use tests :) follow code conventions (don't follow this talk code style)
  • 10. DJANGO CMS BEST PRACTICES THE DETAILS Templates inheritance Namespace configuration django CMS Frontend editor django CMS Toolbar Meta tags Haystack integration
  • 11. DJANGO CMS BEST PRACTICES LET'S START We will use djangocms_blog as a base List of posts Post detail view Tags Categories Comments ...
  • 12. DJANGO CMS BEST PRACTICES TEMPLATES INHERITANCE Use django CMS page templates! {% extends CMS_TEMPLATE %} {% block meta %}     {%  if meta %}         {% include "meta_mixin/meta.html" %}     {% endif %} {% endblock meta %} {% block content %} <div class="app app­blog span8">     {% block content_blog %}{% endblock %} </div> {% endblock content %}
  • 13. DJANGO CMS BEST PRACTICES TEMPLATE RULES Extends CMS_TEMPLATEvariable Define a conventional blockeach application should redefine We'll see the meta_mixin/meta.htmlinclude later
  • 14. DJANGO CMS BEST PRACTICES TEMPLATES LAYOUT Divide application template from plugin ones
  • 15. DJANGO CMS BEST PRACTICES TEMPLATES LAYOUT Use includes to share the common code​ <div class="plugin plugin­blog"><div class="blog­latest­entries">     {% for post in posts_list %}         {% include "djangocms_blog/includes/blog_item.html" with post=post     {% empty %}         <p class="blog­empty">{% trans "No article found." %}</p>     {% endfor %}     </div></div>
  • 16. DJANGO CMS BEST PRACTICES NAMESPACE SUPPORT Django built in support: from django.conf.urls import include, patterns, url urlpatterns = patterns('',     url(r'^blog/', include('djangocms_blog.urls', namespace='blog1'     url(r'^other­blog/', include('djangocms_blog.urls', namespace='blog2' ) my_url = reverse('djangocms_blog:index', current_app='blog1') my_url = reverse('djangocms_blog:index', current_app=request.resolver_matc
  • 17. DJANGO CMS BEST PRACTICES DJANGO CMS SUPPORT django CMS just uses Django's own class BlogApp(CMSApp):     name = _('Blog')     urls = ['djangocms_blog.urls']     app_name = 'djangocms_blog' apphook_pool.register(BlogApp)
  • 18. DJANGO CMS BEST PRACTICES NEW IN 3.1! Enter aldryn-apphooks-config class BlogConfig(TranslatableModel, AppHookConfig):     paginate_by = models.PositiveIntegerField(         _('Paginate size'),         blank=False,         default=5,     )     ... class NewsBlogConfigForm(AppDataForm):     pass setup_config(NewsBlogConfigForm, NewsBlogConfig)
  • 19. DJANGO CMS BEST PRACTICES ALDRYN-APPHOOKS- CONFIG Integrated with django CMS namespace instance creation Definition of per-namespace instance options Tied to each model instance class Post(ModelMeta, TranslatableModel):    ...    app_config = models.ForeignKey(BlogConfig,         verbose_name=_('app. config'))
  • 20. DJANGO CMS BEST PRACTICES IN VIEWS AppConfigMixin: sets up the namespace support retrieves the current configuration class PostListView(AppConfigMixin, ViewUrlMixin, ListView):     model = Post     context_object_name = 'post_list'     template_name = 'djangocms_blog/post_list.html'     view_url_name = 'djangocms_blog:posts­latest'     def get_paginate_by(self, queryset):         return self.app_config.paginate_by
  • 21. DJANGO CMS BEST PRACTICES IN THE ADMIN Use ModelAppHookConfigto get options values (e.g. in admin forms) class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin                 PlaceholderAdminMixin, TranslatableAdmin, ModelAppHookConf                 admin.ModelAdmin):     app_config_values = {         'default_published': 'publish'     }
  • 22. DJANGO CMS BEST PRACTICES IN THE TEMPLATE Access the related namespace instance config through the current model {% if post.app_config.use_placeholder %}     <div class="blog­content">{% render_placeholder post.content %} {% else %}     <div class="blog­content">{% render_model post "post_text" "post_text" {% endif %}
  • 23. DJANGO CMS BEST PRACTICES DJANGO CMS FRONTEND EDITOR
  • 24.
  • 25. DJANGO CMS BEST PRACTICES DJANGO CMS FRONTEND EDITOR Base for plugins behaviour A wrapper around standard Django admin Available for all Django applications
  • 26. DJANGO CMS BEST PRACTICES USE IT! Add FrontendEditableAdminMixin class PostAdmin(FrontendEditableAdminMixin,                 PlaceholderAdminMixin, TranslatableAdmin,                 admin.ModelAdmin):     model = Post     frontend_editable_fields = ('title', 'abstract', 'post_text')     ...
  • 27. DJANGO CMS BEST PRACTICES USE IT! Add template magic <h2>{% render_model post "title" %}</h2> <div class="blog­content"> {% render_model post "post_text" "post_text" %} </div> Edit the whole post Or just some fields
  • 28. DJANGO CMS BEST PRACTICES USE IT!
  • 29. DJANGO CMS BEST PRACTICES POWER TO THE USERS Toolbar is the main django CMS UI
  • 30.
  • 31. DJANGO CMS BEST PRACTICES POWER TO THE USERS Available to all Django applications
  • 32.
  • 33. DJANGO CMS BEST PRACTICES HOW TO IMPLEMENT IT Toolbar is very rich and powerful I'll just show the basics Check documentation for details http://django-cms.rtfd.org/en/develop/how_to/toolbar.html
  • 34. DJANGO CMS BEST PRACTICES HOW TO IMPLEMENT IT Create cms_toolbar.py Define the links to the admin views @toolbar_pool.register class BlogToolbar(CMSToolbar):     watch_models = [Post]     def populate(self):         if not self.is_current_app:             return         admin_menu = self.toolbar.get_or_create_menu(              'djangocms_blog', _('Blog'))         url = reverse('admin:djangocms_blog_post_changelist')         admin_menu.add_modal_item(_('Post list'), url=url)         url = reverse('admin:djangocms_blog_post_add')         admin_menu.add_modal_item(_('Add post'), url=url)  
  • 35. DJANGO CMS BEST PRACTICES HOW TO IMPLEMENT IT Add contextual-aware links current_post = getattr(self.request, BLOG_CURRENT_POST_IDENTIFIER) if current_post:     admin_menu.add_modal_item(_('Edit Post'),         reverse(             'admin:djangocms_blog_post_change',                 args=(current_post.pk,)         ), active=True) class PostDetailView(TranslatableSlugMixin, BaseBlogView, DetailView)     model = Post     def get_context_data(self, **kwargs):         context = super(PostDetailView, self).get_context_data(**kwargs)         setattr(self.request, BLOG_CURRENT_POST_IDENTIFIER, self.get_objec         return context
  • 36. DJANGO CMS BEST PRACTICES SOME NOTES Redirect browser to current post upon edit class BlogToolbar(CMSToolbar):     watch_models = [Post] Hide the application toolbar item when outside the application URLs def populate(self):     if not self.is_current_app:         return
  • 37. DJANGO CMS BEST PRACTICES SHARE THE PASSION! Content is dumb without metadata schema.org OpenGraph ... Metadata defines the meaning of the content
  • 38. DJANGO CMS BEST PRACTICES DJANGO CMS HAS GOT THAT COVERED! django-meta/ django-meta-mixin Django applications to format document metadata: title author image ...
  • 39. DJANGO CMS BEST PRACTICES AN EXAMPLE Define an attribute that maps metadata properties to attribute/function/callable Include a template ... That's all  
  • 40. DJANGO CMS BEST PRACTICES THE MODEL _metadata = {     'title': 'get_title',     'description': 'get_description',     'og_description': 'get_description',     'image': 'get_image_full_url',     'object_type': get_setting('TYPE'),     .... } def get_title(self):     title = self.safe_translation_getter('meta_title')     if not title:         title = self.safe_translation_getter('title')     return title.strip() def get_image_full_url(self):
  • 41. DJANGO CMS BEST PRACTICES THE VIEW as_meta()method does the magic def get_context_data(self, **kwargs):     context = super(MyView, self).get_context_data(**kwargs)     context['meta'] = self.get_object().as_meta()     return context
  • 42. DJANGO CMS BEST PRACTICES THE TEMPLATE Templates are even easier <head>     ...     {% include "meta_mixin/meta.html" %}     ... </head>
  • 43. DJANGO CMS BEST PRACTICES IT'S DONE <meta property="og:title" content="L'evento Djangobeer a Firenze, organizz <meta property="og:url" content="http://www.nephila.it/it/blog/2014/09/18/ <meta property="og:description" content="La prima Djangobeer a Firenze: co <meta property="og:image" content="http://www.nephila.it/media/filer_publi <meta property="og:type" content="Article"> <meta property="article:published_time" content="2014­09­18 18:03:20" <meta property="article:modified_time" content="2014­12­24 11:44:15.769410 <meta name="twitter:domain" content="www.nephila.it"> <meta name="twitter:card" content="Summary"> <meta name="twitter:title" content="L'evento Djangobeer a Firenze, organiz <meta name="twitter:url" content="http://www.nephila.it/it/blog/2014/09/18 <meta name="twitter:description" content="La prima Djangobeer a Firenze: c <meta name="twitter:image:src" content="http://www.nephila.it/media/filer_ <meta name="twitter:creator" content="@NephilaIt"> <meta name="twitter:site" content="@nephilait"> <link rel="author" href="https://plus.google.com/+NephilaIt"/>
  • 44. DJANGO CMS BEST PRACTICES THE IMPORTANCE OF BEING INDEXED What if I want to make my content indexable? aldryn_search to the rescue Easier binding between Haystack and your models Knows a few things of django CMS
  • 45. DJANGO CMS BEST PRACTICES HOW TO CREATE THE INDEX search_indexes.py class PostIndex(get_index_base()):     def get_title(self, obj):         return obj.get_title()     def index_queryset(self, using=None):         self._get_backend(using)         language = self.get_current_language(using)         filter_kwargs = self.get_index_kwargs(language)         qs = self.get_index_queryset(language)         if filter_kwargs:             return qs.translated(language, **filter_kwargs)         return qs     def get_index_queryset(self, language):         return self.get_model().objects.active_translations(             language_code=language).filter(app_config__search_indexed=
  • 46. DJANGO CMS BEST PRACTICES HOW TO CREATE THE INDEX #2 def get_search_data(self, language=None, request=None):         """         Provides an index for use with Haystack, or, for populating         Article.translations.search_data.         """         if not self.pk:             return ''         if language is None:             language = get_language()         if request is None:             request = get_request(language=language)         description = self.safe_translation_getter('lead_in')         text_bits = [strip_tags(description)]         for category in self.categories.all():             text_bits.append(                 force_unicode(category.safe_translation_getter('name'
  • 47. DJANGO CMS BEST PRACTICES CONFUSED? It may looks complex at first Have a look at other examples aldryn-newsblog djangocms-blog aldryn-events  
  • 48. DJANGO CMS BEST PRACTICES TO BE CONTINUED... There's more to come! Content versioning support Managing draft/live copy version of objects Your suggestions A detailed white paper in the next months