Download - Django 1.5 における効果的な MTV 設計 & ネイティブApp
Django 1.5 MTV & App
@luyikei
@luyikei
Linux Mint, Qt, Django
1, DjangoMTVModel : 1, Model Relationships 2, Mata Options Template : 1, Python Template Engine 2, Custom tags and filters
View : 1, Sessions 2, Cookie 3, Cache
2,API OAuth (PyQt )
MTV
MTV
Django appears to be a MVC framework, but you call the Controller the view, and the View the template. How come you dont use the standard names? (https://docs.djangoproject.com/en/dev/faq/general/ )
MVC MTV
Django
Django URL
( http://www.djangoproject.jp/doc/ja/1.0/faq/general.html )
MVC
Model : 1, Model Relationships
- , -
Model -
Title : Price : 220Vegetable : LettuceMeat : HamOnEgg : True
Model -
Title : Price : 136Guzai : Salmon
class Item(models.Model): title = models.CharField(max_length=200) price = models.IntegerField()
Model
class Sandwich(Item): vegetable = models.CharField(max_length=200) meat = models.CharField(max_length=200) onEgg = models.BooleanField(default=False)
Model
class Onigiri(Item): Guzai = models.CharField(max_length=200)
Item
Onigiri Item.onigiri
Sandwich Item.sandwich
class Item(models.Model): title = models.CharField(max_length=200) price = models.IntegerField() subclass = models.CharField(max_length=200,editable=False) def save(self, *args, **kwargs): # save what kind we are. self.subclass = self.__class__.__name__ super(Item, self).save(*args, **kwargs)
def as_child(self): return getattr(self, self.subclass.lower())
i=Item.objects.get(id=1)child=i.as_child()
Model : 2, Mata Options
Django Meta
Django Models Internals Documentation
https://django-model-_meta-reference.readthedocs.org/en/latest/index.html
get_all_related_objects_with_model
Returns a list of (related-object, model) pairs. Similar to get_fields_with_model().
Related
:[(, None), (, None)]
get_parent_list
Returns a list of all the ancestor of this model as a list. Useful for determining if something is an ancestor, regardless of lineage.
()( list set )
:set([])
get_latest_by
model Manager latest() , earliest()
:get_latest_by = "order_date"
ordering
:ordering = ['-order_date']
db_table
:db_table = 'music_album'
Template : 1, Python Template Engine
Django TemplateJinja2MakoChameleon
Django Template
Django Django HTML Smarty CheetahTemplate Django
PHP HTML Django HTML Python
http://docs.djangoproject.jp/en/latest/topics/templates.html
Test[a] {{ Test.a }}Test[a][b] {{ Test.a.b }}Test[a].b() {{ Test.a.b }}Test.a.b {{ Test.a.b }}
Jinja 2
Django Template
Django Template
Method Calls: a.b() {{ a.b() }} () a[b] {{ a[b] }} ()Conditions: {% ifequal a b %} {% if a == b%} Filter Arguments: {{ items|join:", " }} {{ items|join(', ') }}
Mako
% for row in rows: ${makerow(row)} % endfor
% for name in row: ${name}\ % endfor
Mako =
Django Template
Django
Test[a] ${ Test[a] }Test[a][b] ${ Test[a][b] }Test[a].b() ${ Test[a].b() }Test.a.b ${ Test.a.b }
Chameleon
These are your items:
Chameleon TAL
TAL Zope Chameleon
XML
Django XML
Django XML/HTML
Django World Online email JavaScript CSV
http://docs.djangoproject.jp/ja/latest/topics/templates.html
:polls/ models.py templatetags/ __init__.py poll_extras.py views.py
Django templatetags
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
Django XML
: XML
http://docs.djangoproject.jp/ja/latest/topics/templates.html
Template : 2, Custom tags and filters
Django Template
django/template/defaultfilters.py
from django.template.base import Libraryregister = Library()
@register.filter(is_safe=True)@stringfilterdef lower(value): """Converts a string into all lowercase.""" return value.lower()
Django
Python
:polls/ models.py templatetags/ __init__.py poll_extras.py views.py
Django templatetags
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
:from django.template.base import Libraryregister = Library()
@register.filter()def nothing(value): pass
:from django.template.base import Libraryregister = Library()
@register.tagdef nothing(value): pass
View : 1, Sessions
HTTPCookie
http://d.hatena.ne.jp/keyword/%A5%BB%A5%C3%A5%B7%A5%E7%A5%F3
request.session[Height] = 120
:
request.session.get('Height', 0):
get(key, default=None): fav_color = request.session.get('fav_color', 'red')
:
del request.session[Height]
View : 2, Cookie
HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False)
response = render_to_response(template_name, context)
response.set_cookie('Height', ') return response
HttpResponse.set_cookie
request.COOKIES.get('Height')
View : 3, Cache
http://e-words.jp/w/E382ADE383A3E38383E382B7E383A5.html
Memcached ()
:Memcached
settings.py CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '127.0.0.1:11211', }}
MIDDLEWARE_CLASSES = ( 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware',)
http://docs.djangoproject.jp/en/latest/topics/cache.html#id10
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)def my_view(request):
from django.views.decorators.cache import cache_page
urlpatterns = ('', (r'^foo/(\d{1,2})/$', cache_page(60 * 15)(my_view)),)
http://docs.djangoproject.jp/en/latest/topics/cache.html#id10
{% load cache %}{% cache 500 sidebar %} .. sidebar ..{% endcache %}
http://docs.djangoproject.jp/en/latest/topics/cache.html#id10
2,
Django
Qt
OAuth
OAuth OAuth ( [1]) WebAPI (authorization) (Wikipedia)
API
http://www.atmarkit.co.jp/fsecurity/rensai/digid01/02.html
Django OAuth2 django-oauth-plus
Django API django-tastypie
INSTALLED_APPS
INSTALLED_APPS = ( 'tastypie', 'oauth_provider',)
API
common/api.py
from tastypie.resources import ModelResourcefrom common.models import Onigiri
class OnigiriResource(ModelResource): class Meta: queryset = Onigiri.objects.all() resource_name = 'onigiri
Urls
ecsite/urls.py
from tastypie.api import Api
from django.contrib import adminadmin.autodiscover()onigiri_resource = OnigiriResource()
v1_api = Api(api_name='v1')v1_api.register(OnigiriResource())
urlpatterns = patterns('', url(r'^api/', include(onigiri_resource.urls)),)
()
$ curl http://127.0.0.1:8000/api/v1/onigiri/?format=json{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}, "objects": [{"guzai": "gre", "id": 1, "price": 436, "resource_uri": "/admin/v1/onigiri/1/", "subclass": "Onigiri", "title": "sdg"}]}
However, if you try sending a POST/PUT/DELETE to the resource, you find yourself getting 401 Unauthorized errors. For safety, Tastypie ships with the authorization class (what are you allowed to do) set to ReadOnlyAuthorization. This makes it safe to expose on the web, but prevents us from doing POST/PUT/DELETE. Lets enable those:
http://django-tastypie.readthedocs.org/en/latest/tutorial.html
POST/PUT/DELETE API
common/api.py
from tastypie.authentication import OAuthAuthenticationfrom tastypie.authorization import DjangoAuthorizationfrom tastypie.resources import ModelResourcefrom common.models import Onigiri
class OnigiriResource(ModelResource): class Meta: queryset = Onigiri.objects.all() resource_name = 'onigiri authentication = OAuthAuthentication() authorization = DjangoAuthorization
$ curl http://127.0.0.1:8000/api/v1/onigiri/?format=jsoInvalid request parameters.
OAuth
: Consumer
$ ./manage.py shell>>> from oauth_provider.models import Consumer, Token>>> c = Consumer()>>> c.generate_random_codes()>>> c
>>> c.keyu'b10945ea448344bb8d2c7f33d38f2f0d'>>> c.secretU'AQsJnvVYn04njIVK'
http://d.hatena.ne.jp/yuheiomori0718/20120924/1348496794
: Token
$ ./manage.py shell>>> from django.contrib.auth.models import User>>> u = User.objects.all()[0]>>> t = Token()>>> t.user = u>>> t.consumer = c>>> t.token_type = 2>>> t.resource_id=0>>> t.generate_random_codes()>>> t.key'bec4fdc33725458ab2894558014844b7'>>> t.secretU'WgKrSb7QMz9CLZyX'http://d.hatena.ne.jp/yuheiomori0718/20120924/1348496794
# coding=utf-8import jsonimport requestsfrom oauth_hook import OAuthHook
consumer_key = 'b10945ea448344bb8d2c7f33d38f2f0d'consumer_secret = 'AQsJnvVYn04njIVK'access_token = 'bec4fdc33725458ab2894558014844b7'access_token_secret = 'WgKrSb7QMz9CLZyX'
oauth_hook = OAuthHook(access_token=access_token, access_token_secret=access_token_secret, consumer_key=consumer_key, consumer_secret=consumer_secret, header_auth=True)
request = requests.Request('GET', "http://127.0.0.1:8000/api/v1/onigiri/?format=json")request = oauth_hook(request)prepared = request.prepare()
session = requests.session()resp = session.send(prepared)
print resp.text
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 1}, "objects": [{"guzai": "gre", "id": 1, "price": 436, "resource_uri": "/api/v1/onigiri/1/", "subclass": "Onigiri", "title": "sdg"}]}
PyQt