Přejít k navigační liště

Zdroják » Různé » Django: Rozšiřování možností Djanga

Django: Rozšiřování možností Djanga

Články Různé

Holá instalace Djanga má mnoho různých funkcí. Určitě však časem zjistíme, že nám nějaká maličkost chybí. Proto se v tomto díle podíváme na několik ukázek možného rozšíření.

Přidání vlastního filtru do šablony

Určitě si vzpomínáte na šestý díl seriálu, kde jsme se učili prezentovat data pomocí generických pohledů. V příkladu jsme si vypsali mimo jiné e-mailovou adresu provozovny. Tyto adresy nejsou nijak chráněné, takže je může zaznamenat i ten nejhloupější spambot, což představuje problém. Proto si napíšeme jednoduchý filtr, pomocí kterého e-mailovou adresu transformujeme do zakódovaného řetězce v JavaScriptu.

Filtr je vlastně obyčejná funkce, které předáme nějaký vstup a ona vrátí odpovídající výstup. Každá aplikace, která je uvedená v konstantě INSTALLED_APPS v souboru settings.py, může mít svou sadu filtrů a značek. Stačí v adresáři aplikace (v našem případě video_store) vytvořit podadresář templatetags a umístit do něj dva soubory. První je potřeba pojmenovat __init__.py a bude stačit, když bude prázdný. Označuje totiž, že daný adresář obsahuje modul napsaný v Pythonu. Druhý soubor můžeme pojmenovat libovolně, já si zvolil název misc.py, protože do tohoto souboru potom možná časem přidám další různorodé funkce (anglicky miscellaneous). Obsah souboru vypadá takto:

# coding: utf-8
from base64 import b64encode
from django import template
from django.utils.safestring import mark_safe
from django.template.defaultfilters import stringfilter

register = template.Library()

@register.filter
@stringfilter
def email(value):
    return mark_safe('<script type="text/javascript">display_email("%s");</script><noscript>(e-mail je chráněn JavaScriptem)</noscript>' % b64encode(value))

Na sedmém řádku se nachází přiřazení, které určuje, že se jedná o knihovnu filtrů a značek. Proměnná se musí jmenovat register a musí obsahovat objekt template.Library — takto to stanovuje konvence. Na devátém a desátém řádku můžeme vidět dva dekorátory. První z nich (@register.filter) registruje nový filtr. Kdybychom chtěli přidat novou značku, napíšeme místo toho @register.tag. Tento dekorátor má nepovinný parametr name, jež určuje název nového filtru či značky. My jsme ho vynechali, takže se název filtru odvodí z názvu funkce. Druhý dekorátor dbá na to, aby funkce dostala jako vstup řetězec. V případě, kdy by filtr byl připojen např. k číslu, by při zpracování šablony došlo k vyhození výjimky AttributeError. Tento dekorátor také převádí objekty na řetězce voláním metod __str__ nebo __unicode__.

Samotný filtr vezme hodnotu a vrátí HTML kód s JavaScriptem. Funkce mark_safe označí řetězec za bezpečný. Nedojde tak k automatickému escapování HTML značek a entit, takže se kupříkladu místo kódu &lt;noscript&gt; vypíše očekávaná hodnota <noscript>. Tuto vlastnost vypínejte s rozmyslem, hlavně při vypisování uživatelem zadaných dat. Pokud byste chtěli ošetřit uživatelem zadaná data sami, můžete k tomuto účelu použít funkci escape z modulu django.utils.html. V našem případě zaručíme bezpečnost vstupu tím, že ho zakódujeme pomocí kódování base64, které obsahuje pouze písmena abecedy, číslice a znaky plus, lomítko a rovnítko (viz RFC 3548). Takto zakódovaný e-mail spambot rozezná těžko.

Dále nesmíme zapomenout upravit šablonu s výpisem poboček (templates/stores.html):

{% extends "base.html" %}
{% load misc %}

{% block content %}
<h1>{% block title %}Provozovny{% endblock %}</h1>

{% for object in object_list %}
  <h2>{{ object.store }}</h2>

  <ul class="store">
  <li>{{ object.address }}</li>
  <li>{{ object.city }}</li>
  <li>{{ object.postal_code }}</li>
  {% if object.email %}
    <li>{{ object.email|email }}</li>
  {% endif %}
  </ul>

  {% if object.description %}
    <p>{{ object.description }}</p>
  {% endif %}
{% endfor %}
{% endblock %}

V tomto souboru přibyla na druhém řádku značka pro načtení našeho modulu s filtrem misc.py. Na patnáctém řádku se e-mail nevypisuje přímo, ale přes filtr email což zatím nebude fungovat, protože nemáme definovanou javascriptovou funkci display_email. Přesto se ale můžeme podívat na to, co uvidí uživatelé s vypnutým JavaScriptem.

Django 12

Založíme si tedy někde v adresáři static javascriptový soubor, který poté načteme přes značku &lt;script&gt; v šabloně templates/base.html. Tento soubor bude obsahovat již zmiňovanou funkci pro výpis e-mailu:

function display_email(str) {
    email = b64decode(str);

    document.write('<a href="mailto:' + encodeURI(email) + '">' + email + '</a>');
}

Na druhém řádku se volá funkce b64decode pro převedení zakódovaného řetězce do původní podoby. Ta v JavaScriptu není standardně implementována, takže jsem ji si musel napsat sám. Protože je však celkem rozsáhlá a pro další vysvětlování není potřeba, případní zájemci se na ni mohou podívat v přiloženém ukázkovém příkladu (soubor static/js/scripts.js). Co se týče čtvrtého řádku této funkce, ten zobrazí uživateli klikatelný e-mail.

Django 12

Přidání proměnné do kontextu

Opět navážeme na poznámku ze šestého dílu seriálu, kde jsme se zmínili o kontextových procesorech. Díky nim můžeme v šablonách používat společné proměnné (což je např. {{ MEDIA_URL }} nebo {{ user }}), stačí vždy při volání metody render_to_response uvést parametr context_instance=RequestContext(request). Konstanta TEMPLATE_CONTEXT_PROCESSORS určuje, které kontextové procesory se v projektu použijí. V dokumentaci Djanga je popsáno několik základních procesorů, my si napíšeme vlastní.

Zadavatel našeho projektu dostal šílený nápad, že by se v hlavičce webu měla zobrazovat náhodně některá z předem připravených marketingových hlášek. Protože se tato funkce týká všech pohledů, při implementaci přímo v pohledech, by došlo k zbytečnému duplikování kódu. K tomuto účelu je lepší vybranou hlášku předat šabloně jako globální kontext. Náhodné vypisování by se to sice dalo vyřešit jednoduchým kódem v JavaScriptu, ale myslím, že skriptování v prohlížeči už dnes bylo dost.

Soubor s funkcí, která přidává další kontext, si můžeme založit kdekoliv. Například přímo v adresáři projektu. Pojmenujeme ho jako context_processors.py:

# coding: utf-8

from random import choice

def nonsense(request):
    quotes = [
        'Jsme nejlepší!',
        'Naše tituly do vašeho přehrávače.',
        'Dobrý den je, když si pustíte film.',
        'Je přece správné platit za půjčování.',
        'Tohle u konkurence nenajdete.',
    ]

    return {'NONSENSE': choice(quotes)}

Funkce pro přidání kontextu požaduje jako parametr objekt Request a vrací slovník s deklaracemi proměnných. Bývá zvykem proměnné z kontextového procesoru zapisovat verzálkami, aby se odlišily od těch z pohledů. V naší funkci náhodně vybíráme jeden z blábolů, ke kterému poté budeme mít možnost přistupovat pomocí proměnné {{ NONSENSE }}.

Tento kontextový procesor je potřeba přidat do nastavení. Otevřeme si tedy soubor settings.py a dopíšeme do něj následující řádky:

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'hrajeme_si.context_processors.nonsense',
)

První čtyři procesory jsou výchozí, ten poslední je náš. Teď už stačí jenom upravit v hlavní šabloně templates/base.html horní část webu:

<div id="header">
Videopůjčovny s. r. o.
{% if NONSENSE %}
  <div id="nonsense">{{ NONSENSE }}</div>
{% endif %}
</div>

Django 12

Související odkazy

Příště se podíváme na tvorbu vícejazyčných webů.

Komentáře

Odebírat
Upozornit na
guest
0 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
Zobrazit všechny komentáře

Austrálie vs. sociální sítě: ochrana dětí nebo absurdní regulace?

Různé
Komentáře: 1
Austrálie chystá razantní krok – od prosince 2025 budou děti mladší 16 let muset opustit sociální sítě. Ministryně komunikací Anika Wells ujistila, že vláda se nenechá zastrašit technologickými giganty. Zákon má chránit mladé uživatele před negativními dopady online světa, ale kritici varují, že může vést spíš k obcházení pravidel než k reálné ochraně.

Tor přechází na nový šifrovací algoritmus CGO

Různé
Komentáře: 0
Tor Project představil nový šifrovací algoritmus Counter Galois Onion (CGO), který nahrazuje zastaralý systém tor1. CGO přináší výrazně lepší ochranu proti manipulaci a sledování, zajišťuje forward secrecy a silnou autentizaci přenášených dat, přičemž zachovává vysokou výkonnost a nízkou režii provozu.

Nové Visual Studio 2026 a .NET 10

Různé
Komentáře: 0
Visual Studio 2026 a .NET 10 přinášejí moderní vývojové prostředí a výkonný framework, který výrazně zrychluje práci vývojářů, zlepšuje produktivitu a podporuje nejnovější technologie. V článku se podíváme na hlavní novinky, včetně AI asistence, moderního UI, optimalizovaného runtime a jazykových vylepšení v C# 14, a ukážeme si, na co si dát pozor při přechodu na nové verze.