Django boodoo

  • View
    1.275

  • Download
    0

Embed Size (px)

DESCRIPTION

This slides introduce a few (slightly maniac) usage of {% with %} template tag and a hack of django-integrated multi DB.

Text of Django boodoo

  • 1. Django @whosaysni

2. (@whosaysni)! http://whosaysni.jp/! ! ! ! PyConJP! PyConJP 9/13-15 CFP! http://2014.pycon.jp/! ! .py ! https://sites.google.com/site/oikamipy/ 3. Django 4. Django 5. 6. 0.95 Django 0.98 Unicode 1.0 1.2 DB 1.3 mod_python 1.4 project/app 1.6 User 1.7 7. {% with %} DjangoDB 8. {% with %} 9. {% with %} {% include %} {% with a='foo' b='bar' %}! Outside nest:{{ a }}/{{ b }}/{{ c }}.! {% with c=a b='baz' %}! Inside nest: {{ a }}/{{ b }}/{{ c }}.! {% endwith %}! {% endwith %} ! Outside nest: foo/bar/.! Inside nest: foo/baz/foo. 10. {% with %} {% with a=123 c='defg' e=hij ... %} a=123 a as 123 11. {% with %} (1) @register.tag('with')def do_with(parser, token): ... bits = token.split_contents() remaining_bits = bits[1:] extra_context = token_kwargs(remaining_bits, parser, support_legacy=True) if not extra_context: raise TemplateSyntaxError("%r expected at least one variable " "assignment" % bits[0]) if remaining_bits: raise TemplateSyntaxError("%r received an invalid token: %r" % (bits[0], remaining_bits[0])) nodelist = parser.parse(('endwith',)) parser.delete_first_token() return WithNode(None, None, nodelist, extra_context=extra_context) with endwith 12. {% with %} (2) class WithNode(Node): def __init__(self, var, name, nodelist, extra_context=None): self.nodelist = nodelist # var and name are legacy attributes, being left in case they are used # by third-party subclasses of this Node. self.extra_context = extra_context or {} if name: self.extra_context[name] = var! def __repr__(self): return ""! def render(self, context): values = dict([(key, val.resolve(context)) for key, val in six.iteritems(self.extra_context)]) context.update(values) output = self.nodelist.render(context) context.pop() return output 13. context['color'] -> 'blue' context['number'] -> 2 context['food'] -> 'spam' Context number=42 food='spam' animal='duck' color='blue' number=2 dict dict dict 14. {% with %} with 15. 16. #1: username username username {{ username }} {{ username|default:'' }} OK {{ username|default:' ' }}! ...! {{ username|default:'' }} ! ...! {{ username|default:'' }} ! ....(#);:'! 17. #1: {% with username=username|default:'' %}! {{ username }}! ...! {{ username }}! ...! {{ username }}! ....! {% endwith %} {% with %} {% with %} 18. #2: {% include %} Hello {{ foo }}. {% include %} include {% with foo='bar' %}! {% include "included.html" %}! {% endwith %} Hello bar. 19. #2: {% include %} {{ field.label_tag }}

{{ field.help_text }}

{% with field_type=type|default:"" %}
{% ifequal field_type "" %} {{ field }} {% endifequal %} {% ifequal field_type "text" %} {{ field }} {% endifequal %} {% ifequal field_type "password" %} {{ field }} {% endifequal %} {% ifequal field_type "switch" %} {{ field }} {% endifequal %} {{ field.errors.as_text }}
{% endwith %}

widget eld.html 20. #2: {% include %}

Add user
{% csrf_token %} {% with field=form.is_superuser type='switch' %}{% include "field.html" %}{% endwith %} {% with field=form.is_active type='switch' %}{% include "field.html" %}{% endwith %} {% with field=form.username type='text' %}{% include "field.html" %}{% endwith %} {% with field=form.password type='password' %}{% include "field.html" %}{% endwith %} {% with field=form.email type='text' %}{% include "field.html" %}{% endwith %} {% with field=form.first_name type='text' %}{% include "field.html" %}{% endwith %} {% with field=form.last_name type='text' %}{% include "field.html" %}{% endwith %}

2 21. Multi-DB 22. Django Multi-DB 1.2 DB DB Django App Replicate/Partition RO Access RW Access 23. Multi-DB settings DB using() BE_PG = 'django.db.backends.postgresql_psycopg2'BE_MY = 'django.db.backends.mysql'DATABASES = { 'default': { 'NAME': 'master_db', 'ENGINE': BE_PG, 'USER': 'master_user', 'PASSWORD': 'boo hoo woo' }, 'replicon': { 'NAME': 'replicon_db', 'ENGINE': BE_MY, 'USER': 'replicon_user', 'PASSWORD': 'let it go' }} # User.objects.using('users').get(...)! # class MyDbRouter(object): def db_for_read(self, model, **kw): if ...: return 'replicon'DATABASE_ROUTERS = ['foo.bar.MyDbRouter',...] 24. Multi-DB django.db.connections DB connections ConnectionHandler fromdjango.dbimportconnections ! classQuerySet(object): """ Representsalazydatabaselookupforasetofobjects. """ def__init__(self,model=None,query=None,using=None): self.model=model self._db=using self.query=queryorsql.Query(self.model) ... ! def... connection=connections[self.db] django.db.models.query fromdjango.db.utilsimportConnectionHandler connections=ConnectionHandler() django.db.__init__ 25. Multi-DB ConnectionHandlerDB __getitem__ classConnectionHandler(object): def__init__(self,databases=None): self._databases=databases self._connections=local() ! ... ! def__getitem__(self,alias): ifhasattr(self._connections,alias): returngetattr(self._connections,alias) ! self.ensure_defaults(alias) db=self.databases[alias] backend=load_backend(db['ENGINE']) conn=backend.DatabaseWrapper(db,alias) setattr(self._connections,alias,conn) returnconn django.db.utils 26. ConnectionHandler DB DBPythonDjango 27. https://gist.github.com/whosaysni/11361218 28. Thanks!