Відмінності між версіями «Django FAQ»

Матеріал з Wiki Welard
Перейти до навігації Перейти до пошуку
Рядок 52: Рядок 52:
 
== Збереження в змінній форми ==
 
== Збереження в змінній форми ==
 
allNodes = Form.serialize("myform");  
 
allNodes = Form.serialize("myform");  
−
 
  
 
== Профілі користувачів  ==
 
== Профілі користувачів  ==
Рядок 64: Рядок 63:
 
  u = User.objects.get(username='test')
 
  u = User.objects.get(username='test')
 
  user_profile = u.profile.get()
 
  user_profile = u.profile.get()
−
 
  
 
== Pagination - розбиття на сторінки ==
 
== Pagination - розбиття на сторінки ==
Рядок 73: Рядок 71:
 
  page1.object_list
 
  page1.object_list
  
−
<br> 8. Багатомовність  
+
== Багатомовність ==
−
 
 
 
     django-admin.py makemessages -l uk
 
     django-admin.py makemessages -l uk
 
     django-admin.py compilemessages
 
     django-admin.py compilemessages
  
−
9. Групиування в SQL  
+
== Групування в SQL ==
−
 
+
 
  qs = Schedule.objects.select_related().filter(pub_date__gte=datetime.now())
 
  qs = Schedule.objects.select_related().filter(pub_date__gte=datetime.now())
 
  qs.query.group_by = ['country_id'] #!!!!!!
 
  qs.query.group_by = ['country_id'] #!!!!!!
Рядок 90: Рядок 87:
 
     &gt;&gt;&gt; item_types
 
     &gt;&gt;&gt; item_types
  
−
10. Кешування процедури
+
== Дописування методів в адмінку ==
−
 
 
−
@cached( trigger = { "signal"&nbsp;: ( signals.post_save, signals.post_delete ),"sender"&nbsp;: Post  } )
 
−
def get_latest_posts():
 
−
    return list( Post.objects.all().order_by( "-date" )[:5] )
 
−
 
 
−
11. Дописування методів в адмінку  
 
−
 
 
 
     def remove(self):
 
     def remove(self):
 
         from django.core.urlresolvers import reverse
 
         from django.core.urlresolvers import reverse
Рядок 104: Рядок 94:
 
     remove.allow_tags = True
 
     remove.allow_tags = True
  
−
12. Приклад WSGI  
+
== Приклад WSGI ==
  
 
  sys.stdout = sys.stderr
 
  sys.stdout = sys.stderr
Рядок 115: Рядок 105:
 
  application = django.core.handlers.wsgi.WSGIHandler()
 
  application = django.core.handlers.wsgi.WSGIHandler()
  
−
13. Профілі користувачів  
+
== Профілі користувачів ==
  
 
  from django.contrib import admin
 
  from django.contrib import admin
Рядок 130: Рядок 120:
 
     admin.site.register(User, ProfileAdmin)
 
     admin.site.register(User, ProfileAdmin)
  
−
14. Профілі 2  
+
== Профілі 2 ==
  
 
  from django.contrib.auth.models import User
 
  from django.contrib.auth.models import User
Рядок 143: Рядок 133:
 
  User.add_to_class("get_user_name",get_user_name)
 
  User.add_to_class("get_user_name",get_user_name)
  
−
<br> 15. Якщо є яйця в пітоні  
+
== Якщо є яйця в пітоні ==
  
 
  /etc/sysconfig/httpd
 
  /etc/sysconfig/httpd
 
  export PYTHON_EGG_CACHE="/var/cache/python-eggs"  
 
  export PYTHON_EGG_CACHE="/var/cache/python-eggs"  
  
−
16. Кеш в Django
+
== Кеш в Апачі ==
 
добавити в апач конфігурацію
 
добавити в апач конфігурацію
 
  <IfModule mod_expires.c>
 
  <IfModule mod_expires.c>
Рядок 157: Рядок 147:
 
  </IfModule>
 
  </IfModule>
  
−
у файлі views.py:
+
== Кеш в Django ==
 
  from django.views.decorators.cache import cache_page
 
  from django.views.decorators.cache import cache_page
 
  ....
 
  ....
Рядок 173: Рядок 163:
 
     obj.save()
 
     obj.save()
  
−
 
+
== Корзина ==
−
17. Корзина  
 
  
 
  def delete(self, trash=True):
 
  def delete(self, trash=True):
Рядок 183: Рядок 172:
 
         super(SomeModel, self).delete()
 
         super(SomeModel, self).delete()
  
−
18. Використання unordered_list  
+
== Використання unordered_list ==
 
<pre>['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']], then {{ var|unordered_list }} would return:
 
<pre>['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']], then {{ var|unordered_list }} would return:
 
&lt;li&gt;States
 
&lt;li&gt;States
Рядок 196: Рядок 185:
 
&lt;/ul&gt;
 
&lt;/ul&gt;
 
&lt;/li&gt;
 
&lt;/li&gt;
 +
</pre>
  
−
</pre>
+
== Використання календаря ==
−
<br>
 
−
18. Використання календаря
 
 
<pre>class EventSplitDateTime(forms.SplitDateTimeWidget):
 
<pre>class EventSplitDateTime(forms.SplitDateTimeWidget):
 
     def __init__(self, attrs=None):
 
     def __init__(self, attrs=None):
Рядок 215: Рядок 203:
 
     end = forms.DateTimeField(label=ugettext("End"), widget=EventSplitDateTime())
 
     end = forms.DateTimeField(label=ugettext("End"), widget=EventSplitDateTime())
 
</pre>
 
</pre>
−
19. Рестарт WSGI без апача
+
== Рестарт WSGI без апача ==
 
<pre>@never_cache
 
<pre>@never_cache
 
def restart(request):
 
def restart(request):
Рядок 228: Рядок 216:
 
     return HttpResponse(ret, mimetype='text/plain')
 
     return HttpResponse(ret, mimetype='text/plain')
 
</pre>
 
</pre>
−
20. Фільтрація в моделі в зовнішньому ключі
+
== Фільтрація в моделі в зовнішньому ключі ==
 
  models.ForeignKey(Test, limit_choices_to = {'pub_date__lte': datetime.now})
 
  models.ForeignKey(Test, limit_choices_to = {'pub_date__lte': datetime.now})
−
21. Django & Cron
+
 
 +
== Django & Cron ==
 
<pre>
 
<pre>
 
# -*- coding: utf-8 -*-
 
# -*- coding: utf-8 -*-
Рядок 245: Рядок 234:
 
  # python /path/to/project/run.py report.views "send_emails()"
 
  # python /path/to/project/run.py report.views "send_emails()"
  
−
22. Багато з'єднань з базою
+
== Багато з'єднань з базою ==
 
  from django.db import load_backend
 
  from django.db import load_backend
 
  myBackend = load_backend('postgresql_psycopg2') # or 'mysql', 'sqlite3', 'oracle'
 
  myBackend = load_backend('postgresql_psycopg2') # or 'mysql', 'sqlite3', 'oracle'

Версія за 13:01, 26 липня 2010

Основні команди та нюанси при роботі з системою Django

django-admin.py startproject mysite
python manage.py startapp books
python manage.py validate
python manage.py sqlall books
python manage.py syncdb
python manage.py inspectdb

Модуль для роботи із зображеннями

http://www.pythonware.com/products/pil/ 

Створення бази даних

create database exam2 charset=utf8;
ALTER DATABASE exam2 DEFAULT CHARACTER SET 'utf8'

Циклічний перебір

{% cycle 'row1' 'row2' %} 

Перегрупування в шаблоні

     {% regroup people by gender as gender_list %}
     {% regroup people|dictsort:"gender" by gender as gender_list %}
     <ul>
     {% for gender in gender_list %}
        <li>{{ gender.grouper }}
        <ul>
            {% for item in gender.list %}
            <li>{{ item.first_name }} {{ item.last_name }}</li>
            {% endfor %}
        </ul>
        </li>
     {% endfor %}
     </ul>

Шаблон форми

<form method="post" action="">
<dl>
{% for field in form %}
    <dt>{{ field.label_tag }}{% if field.field.required %}*{% endif %}</dt>
    <dd>{{ field }}</dd>
    {% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
    {% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
{% endfor %}
</dl>
<input type="submit" />
</form>

Робота з формою в views.py

instance = Instance(required_field='value')
form = InstanceForm(request.POST, instance=instance)
new_instance = form.save()
instance = form.save(commit=False)
instance.required_field = 'new value'
new_instance = instance.save()

Збереження в змінній форми

allNodes = Form.serialize("myform");

Профілі користувачів

in settings.py:
AUTH_PROFILE_MODULE = 'projectname.UserProfile'

в інших відповідних файлах

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='%(class)s', primary_key=True)
from django.contrib.auth.models import User
u = User.objects.get(username='test')
user_profile = u.profile.get()

Pagination - розбиття на сторінки

from django.core.paginator import Paginator
objects = ['john', 'paul', 'george', 'ringo']
p = Paginator(objects, 2)
page1 = p.page(1)
page1.object_list

Багатомовність

   django-admin.py makemessages -l uk
   django-admin.py compilemessages

Групування в SQL

qs = Schedule.objects.select_related().filter(pub_date__gte=datetime.now())
qs.query.group_by = ['country_id'] #!!!!!!
return {'schedule': qs}
   >>> qs = TumbleItem.objects.all()
   >>> qs.query.group_by = ['item_type']
   >>> qs.query.having = ['COUNT(item_type) > 1']
   >>> item_types = [i.item_type for i in qs]
   >>> item_types

Дописування методів в адмінку

   def remove(self):
       from django.core.urlresolvers import reverse
       return '<a href="%s" class="deletelink">Delete</a>' % reverse( "django.contrib.admin.views.main.delete_stage",
           args = ( self.__class__._meta.app_label, self.__class__.__name__.lower(), self._get_pk_val(), ) )
   remove.allow_tags = True

Приклад WSGI

sys.stdout = sys.stderr
import os, sys
sys.path.append('/usr/lib/python2.4/site-packages/django')
sys.path.append('/var/www/paradise/paradise')
sys.path.append('/var/www/paradise')
os.environ['DJANGO_SETTINGS_MODULE'] = 'paradise.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Профілі користувачів

from django.contrib import admin
from profile.models import UserProfile
from django.contrib.auth.models import User
class ProfileInline(admin.StackedInline):
    model = UserProfile
    extra = 1
    max_num = 1
class ProfileAdmin(admin.ModelAdmin):
    inlines = (ProfileInline,)
    admin.site.unregister(User)  #!!!
    admin.site.register(User, ProfileAdmin)

Профілі 2

from django.contrib.auth.models import User
User.add_to_class('department',models.CharField(max_length=250,blank=True))
User.add_to_class('position',models.CharField(max_length=250,blank=True))
User._meta.admin.fields += (('Custom', {'fields': ('department','position',)}),)
User._meta.admin.list_display += ('department','position',)
def get_user_name(self):
    if self.first_name or self.last_name:
        return self.first_name + " " + self.last_name
    return self.username
User.add_to_class("get_user_name",get_user_name)

Якщо є яйця в пітоні

/etc/sysconfig/httpd
export PYTHON_EGG_CACHE="/var/cache/python-eggs" 

Кеш в Апачі

добавити в апач конфігурацію

<IfModule mod_expires.c>
    <FilesMatch "\.(jpg|gif|png|css|js)$">
         ExpiresActive on
         ExpiresDefault "access plus 3 days"
    </FilesMatch>
</IfModule>

Кеш в Django

from django.views.decorators.cache import cache_page
....
@cache_page(60 * 15)
def show_page(request, url=None, page_num=0):
    ....
    ....

у файлі admin.py:

from django.core.cache import cache
from django.conf import settings
....     
def save_model(self, request, obj, form, change):
    #cache.delete('views.decorators.cache.cache_header.%s./%s/' % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, obj.url))
    cache._cache.flush_all() # ось так для memcache!!! 
    obj.save()

Корзина

def delete(self, trash=True):
    if not self.trashed_at and trash:
        self.trashed_at = datetime.now()
        self.save()
    else:
        super(SomeModel, self).delete()

Використання unordered_list

['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']], then {{ var|unordered_list }} would return:
<li>States
<ul>
        <li>Kansas
        <ul>
                <li>Lawrence</li>
                <li>Topeka</li>
        </ul>
        </li>
        <li>Illinois</li>
</ul>
</li>

Використання календаря

class EventSplitDateTime(forms.SplitDateTimeWidget):
    def __init__(self, attrs=None):
        widgets = [forms.TextInput(attrs={'class': 'vDateField'}), 
                   forms.TextInput(attrs={'class': 'vTimeField'})]
        # Note that we're calling MultiWidget, not SplitDateTimeWidget, because
        # we want to define widgets.
        forms.MultiWidget.__init__(self, widgets, attrs)

    def format_output(self, rendered_widgets):
        return mark_safe(u'%s<br />%s' % (rendered_widgets[0], rendered_widgets[1]))

class EventForm(forms.Form):
    start = forms.DateTimeField(label=ugettext("Start"), widget=EventSplitDateTime())
    end = forms.DateTimeField(label=ugettext("End"), widget=EventSplitDateTime())

Рестарт WSGI без апача

@never_cache
def restart(request):
    ''' Перезапуск демона '''
    if request.META['mod_wsgi.process_group'] != '':
        import signal, os
        os.kill(os.getpid(), signal.SIGINT)
        ret = 'restarted'
    else:
        ret = 'not find porcess_group'
        
    return HttpResponse(ret, mimetype='text/plain')

Фільтрація в моделі в зовнішньому ключі

models.ForeignKey(Test, limit_choices_to = {'pub_date__lte': datetime.now})

Django & Cron

# -*- coding: utf-8 -*-
import sys
import settings
from django.core.management import setup_environ
setup_environ(settings)
module_name = sys.argv[1]
exec('import %s' % module_name)
exec('%s.%s' % (module_name, ' '.join(sys.argv[2:])))

И теперь при помощи этого скрипта мы можем вызывать функции наших “вьюшек” из командной строки и из cron:

# python /path/to/project/run.py report.views "send_emails()"

Багато з'єднань з базою

from django.db import load_backend
myBackend = load_backend('postgresql_psycopg2') # or 'mysql', 'sqlite3', 'oracle'
myConnection = myBackend.DatabaseWrapper({
    'DATABASE_HOST': '192.168.1.1',
    'DATABASE_NAME': 'my_database',
    'DATABASE_OPTIONS': {},
    'DATABASE_PASSWORD': "",
    'DATABASE_PORT': "",
    'DATABASE_USER': "my_user",
    'TIME_ZONE': "America/New_York",})
# Now we can do all the standard raw sql stuff with myConnection.
myCursor = myConnection.cursor()
myCursor.execute("SELECT COUNT(1) FROM my_table;")
myCursor.fetchone()

23. Автоматична перегрузка коду (для Apache)

в конфіг добавляємо

WSGIScriptReloading On
WSGIReloadMechanism Process
$ touch my_project.wsgi

24. Доступ до url адмінки

from django.core import urlresolvers
url = urlresolvers.reverse('admin:mysite_product_change', args=(obj.id,))

25. Фільтрація по датам

extra_data = {"d": "date(created)"}
result = MyModel.objects.extra(extra_data).values('d').annotate(cnt=Count('pk')).order_by()

26. RAW SQL

authors = Author.objects.raw("SELECT *, age(birth_date) as age FROM library_authors")
for author in authors:
    print "%s is %s." % (author.first_name, author.age)

27. Тестовий поштовий сервер

python -m smtpd -n -c DebuggingServer localhost:1025