Django Drops

1.Django Intro

Django Archite

2.Django Install

(1) PIP安裝

sudo apt-get isntall python-pip
sudo pip install Django

(2) 源碼安裝

/usr/local/share/Django/Django-1.8.3.tar.gz
Django-1.8.3
├── AUTHORS
├── build
├── dist
├── django
├── Django.egg-info
├── docs
├── extras
├── INSTALL
├── LICENSE
├── MANIFEST.in
├── PKG-INFO
├── README.rst
├── scripts
├── setup.cfg
├── setup.py
└── tests
sudo python setup.py install 

3.Django Project

(1) 創建項目

root@kallen:Django#django-admin startproject MyProj
root@kallen:Django# tree MyProj/
MyProj/
├── manage.py
└── MyProj
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

_init_.py
Django項目是Python包,這個文件是用來告訴Python這個文件夾當做一個包。在Python術語中,包是一組模塊的集合,主要用來把相似的文件分組,防止出現命名衝突。


manage.py
這個腳本用來管理你的項目,你可以把它看做是你項目的的django-admin.py版本,其實,manage.py和django-admin.py是共用相同的後臺代碼。


settings.py
這是Django項目的主要配置文件,在這個文件裏面,你可以具體說明很多選項,包括數據庫設置、網頁語言、需要turn
on的Django功能。


urls.py
這是另外一個配置文件。你可以把它看做是介於URLS和用來處理它們的Python方法之間的匹配;

(2) 創建應用

root@kallen:Django#python manage.py startapp jobs
└── MyProj
    ├── jobs
    │   ├── admin.py
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── manage.py
    └── MyProj

(3) 創建實體類

from django.db import models
class Job(models.Model):
    pub_date = models.DateField()
    job_title = models.CharField(max_length=50)
    job_description = models.TextField()
    location = models.ForeignKey(Location)
    def __str__(self):
        return "%s (%s)" % (self.job_title, self.location)  

(4) 查看數據庫模式

root@kallen:/home/kallen/Python/Django/MyProj# python manage.py sql jobs
BEGIN;
CREATE TABLE `jobs_location` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `city` varchar(50)NOT NULL,
    `state` varchar(50),
    `country` varchar(50)NOT NULL
);
CREATE TABLE `jobs_job` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `pub_date` date NOT NULL,
    `job_title` varchar(50)NOT NULL,
    `job_description` longtext NOT NULL,
    `location_id` integerNOT NULL
);
ALTER TABLE `jobs_job` ADD CONSTRAINT `location_id_refs_id_35f2feb6` 
FOREIGN KEY (`location_id`) REFERENCES `jobs_location` (`id`);
COMMIT;

【常見錯誤】

$ python manage.py sql jobs
CommandError: App 'jobs' has migrations. Only the sqlmigrate and sqlflush commands
can be used when an app has migrations.

【解決辦法】 刪除jobs下的migrations就可以了;

(5) 檢查數據庫模式

root@kallen:/home/kallen/Python/Django/MyProj#python manage.py validate
/usr/local/lib/python2.7/dist-packages/Django-1.8.3-py2.7.egg/django/core/
management/commands/validate.py:15: RemovedInDjango19Warning:"validate" has 
been deprecated in favor of"check".RemovedInDjango19Warning)
System check identified no issues (0 silenced).
root@kallen:/home/kallen/Python/Django/MyProj#python manage.py makemigrations
Migrations for 'jobs':
0001_initial.py:
- Create model Job
- Create model Location
- Add field location to job
root@kallen:/home/kallen/Python/Django/MyProj#python manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: admin, contenttypes, jobs, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying jobs.0001_initial... OK

(6) 啓動測試服務器

root@kallen:/home/kallen/Python/Django/MyProj#python manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.
August 14,2015-05:55:23
Django version 1.8.3, using settings 'MyProj.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

(7) 後臺管理

root@kallen:/home/kallen/Python/Django/MyProj#python manage.py syncdb

訪問url: http://127.0.0.1:8000/admin

(8) 註冊模型

from django.contrib issmport admin
# Register your models here.

# Register my models of job for mapping 
# utility class Location & Job.
# Kallen Ding, Agu 17 2015

from .models import Location, Job 

admin.site.register(Location)
admin.site.register(Job) 

4.Django QuerySet

(1)條件查詢

條件選取querySet的時候, filter表示 =,exclude表示 !=
querySet.distinct()

 __exact 精確等於 like 'aaa'
__iexact 精確等於 忽略大小寫 ilike 'aaa'
__contains 包含 like '%aaa%'
__icontains 包含 忽略大小寫 ilike '%aaa%',但是對於sqlite來說,contains的作用效果等同於icontains。 
__gt 大於 
__gte 大於等於 
__lt 小於 
__lte 小於等於 
__in 存在於一個list範圍內 
__startswith 以...開頭 
__istartswith 以...開頭 忽略大小寫 
__endswith 以...結尾 
__iendswith 以...結尾,忽略大小寫 
__range 在...範圍內 
__year 日期字段的年份 
__month 日期字段的月份 
__day 日期字段的日 
__isnull=True/False

5.Django Form

在html頁面中,django會自動輸出form表單,而無需自己定義,詳情請參考 The Forms API.

<form id="your-profile" action="/contact" method="post">
<table class="form-table">

(1) 在 <p> 中顯示錶單

{{ form.as_p }}

實際輸出的HTML如下:

<p><label for="id_subject">Subject:</label> 
<input id="id_subject" type="text" name="subject" maxlength="100"/>
</p>
<p><label for="id_message">Message:</label> 
<input type="text" name="message" id="id_message"/>
</p>
<p><label for="id_sender">Sender:</label> 
<input type="email" name="sender" id="id_sender"/>
</p>
<p><label for="id_cc_myself">Cc myself:</label> 
<input type="checkbox" name="cc_myself" id="id_cc_myself"/>
</p>

(2) 在 <ul> 中顯示錶單

{{ form.as_ul }}  

實際輸出的HTML如下:

<li><label for="id_subject">Subject:</label> 
<input id="id_subject" type="text" name="subject" maxlength="100" />
</li>
<li><label for="id_message">Message:</label> 
<input type="text" name="message" id="id_message"/></li>
<li><label for="id_sender">Sender:</label> 
<input type="email" name="sender" id="id_sender"/>
</li>
<li><label for="id_cc_myself">Cc myself:</label> 
<input type="checkbox" name="cc_myself" id="id_cc_myself"/>
</li>

(3) 在 <table> 中顯示錶單

{{ form.as_table }}        

實際輸出的HTML如下:

<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
<tr><th><label for="id_sender">Sender:</label></th><td><input type="email" name="sender" id="id_sender" /></td></tr>
<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>

(4) 以循環形式顯示錶單

{% for field in form %}               
    {{ field.label_tag }}:{{ field }}
    {{ field.errors }}
{% endfor %}

爲了自定義輸出表單的樣式,可以在Form對象中給組件添加 atts 屬性:

attrs={
    'class': 'form-control',
    'placeholder': 'Username'
}

註冊按鈕及Button:

</table>
<p class="submit">
<input type="submit" name="submit" id="submit"class="button-primary" value="註冊信息"/>
</p>
</form>

6.Django Request

request.META

一個Python字典,包含了所有本次HTTP請求的Header信息,比如用戶IP地址和用戶Agent(通常是 瀏覽器的名稱 和 版本號)。

注意,Header信息的完整列表取決於用戶所發送的Header信息和服務器端設置的Header信息。 這個字典中幾個常見的鍵值有:

HTTP_REFERRER 進站前鏈接網頁,如果有
HTTP_USER_AGENT 覽器的user-agent字符串,如果有的話。
例如:

 "Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17".
REMOTE_ADDR

客戶端IP,如:”12.345.67.89” 。

(如果申請是經過代理服務器的話,那麼它可能是以逗號分割的多個IP地址,如:”12.345.67.89,23.456.78.90”)

[注意]

因爲 request.META 是一個普通的Python字典,因此當你試圖訪問一個不存在的鍵時,會觸發一個 KeyError異常;


(HTTP header信息是由用戶的瀏覽器所提交的、不應該給予信任的”額外”數據,因此你總是應該好好設計你的應用以便當一個特定的Header數據不存在時,給出一個優雅的迴應)


你應該用 try/except 語句,或者用Python字典的 get() 方法來處理這些“可能不存在的鍵”:

# BAD!
def ua_display_bad(request):
    ua = request.META['HTTP_USER_AGENT']
    # Might raise KeyError!
    return HttpResponse("Your browser is%s" % ua)

# GOOD (VERSION 1)
def ua_display_good1(request):
    try:
        ua = request.META['HTTP_USER_AGENT']
    exceptKeyError:
        ua ='unknown'
    return HttpResponse("Your browser is%s" % ua)

# GOOD (VERSION 2)
def ua_display_good2(request):
    ua = request.META.get('HTTP_USER_AGENT','unknown')
    return HttpResponse("Your browser is%s" % ua)

7.Static & Media

from django.conf import settings
if settings.DEBUG:
    urlpatterns += patterns('',
        url(r'^upload/(?P<path>.*)$', 
        'django.views.static.serve',
        {'document_root':settings.MEDIA_ROOT}),
    )

8.Migrations

在1.6之前, Django只支持添加新的model到數據庫, 而無法編輯或修改已經存在的model.
Django 1.7 爲我們帶來了三個新命令:

migrate: 用於執行遷移動作
makemigrations: 基於當前的model創建新的遷移策略文件
sqlmigrate: 顯示遷移的SQL語句

值得注意的是,migration是基於App的, 因此, 我們可以針對某些app不啓用migration功能.
migrations的使用非常簡單: 修改model, 比如增加field, 然後運行

    python manager.py makemigrations

你的mmodel會被掃描, 然後與之前的版本作比較, 在app的migrations目錄下生成本次遷移文件.
我們建議查看一下該遷移文件, 確保沒有問題. 然後運行:

    python manager.py migrate

migrate命令會進行比較, 並應用該遷移.

9.Django FAQ

(1) 導入MySQL錯誤

django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module

【解決辦法】安裝mysql-python模塊

安裝步驟:

sudo apt-get install python-setuptools
sudo apt-get install libmysqld-dev
sudo apt-get install libmysqlclient-dev 
sudo apt-get install python-dev
sudo easy_install mysql-python

測試下: 在python交互式窗口,import MySQLdb 試試,不報錯的話,就證明安裝好了。

(2) 導入model對象出錯

>>> from jobs.models import Job
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

【解決辦法】

>>>from django.conf import settings  
>>> settings.configure()

(3) CSRF Verification Failed

Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
    CSRF token missing or incorrect.
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function passes a request to the template's render method.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG =Truein your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.

【解決辦法】

第一種:在表單里加上{% csrf_token %}就行了;

第二種:在Settings裏的MIDDLEWARE_CLASSES增加配置:

'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.csrf.CsrfResponseMiddleware',

方法二不可行:

ImportError: Module "django.middleware.csrf" does not define a "CsrfResponseMiddleware" attribute/class

在測試環境下只需要將這兩行註釋即可;

(4) Exception

Exception happened during processing of request from ('127.0.0.1', 59311)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 593, in process_request_thread
Exception happened during processing of request from ('127.0.0.1', 59312)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 593, in process_request_thread

(5) IPAddressField

arigue.Server.ipaddr: (fields.W900) IPAddressField has been deprecated. Support forit(except in historical migrations) will be removed in Django 1.9.
    HINT: Use GenericIPAddressField instead.

【解決辦法】推薦使用 GenericIPAddressField()

(6) Forbidden

CSRF verification failed. Request aborted.

Help
Reason given for failure:
    CSRF token missing or incorrect.

In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function passes a request to the template's render method.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.

(7) AppRegistryNotReady

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

這個異常是在windows上使django-xadmin時產生的,一直沒解決,望各位知道的Pythoner回覆。


【參考文章】

http://queengina.com/2014/10/15/Django%E7%B3%BB%E5%88%97%EF%BC%88%E4%BA%8C%EF%BC%89/

http://stackoverflow.com/questions/6315960/djangos-querydict-bizarre-behavior-bunches-post-dictionary-into-a-single-key

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章