Django基础(一)

对于所有的web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

一个简单的web程序:

#!/usr/bin/env python
#coding:utf-8
 
import socket
 
def handle_request(client):
    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK\r\n\r\n")
    client.send("Hello, Seven")
 
def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost',8000))
    sock.listen(5)
 
    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()
 
if __name__ == '__main__':
    main()

python web程序一般会分为服务器程序和应用程序。服务器程序负责对socket服务器进行封装,并在请求到来时对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的web框架。例如Django,Flask,web.py等。

不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,再能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说只有支持它的服务器才能被开发出的应用使用。这个时候,标准化就变的尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。

 

WSGI

web server gateway interface 是一种规范,它定义了使用python编写的web app与web server 之间的接口格式,实现   web app与 web server间的解耦。

python标准库提供的独立的wsgi服务器称为wsgiref

#!/usr/bin/env python
#coding:utf-8

from wsgiref.simple_server import make_server

def RunServer(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return '<h1>Hello, web!</h1>'

if __name__ == '__main__':
    httpd = make_server('', 8000, RunServer)
    print "Serving HTTP on port 8000..."
    httpd.serve_forever()

 

自定义web框架

通过python标准库提供的wsgiref模块开发一个自己的web框架

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server

def index():
    return 'index'

def login():
    return 'login'

def routers():
    
    urlpatterns = (
        ('/index/',index),
        ('/login/',login),
    )
    
    return urlpatterns

def RunServer(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']
    urlpatterns = routers()
    func = None
    for item in urlpatterns:
        if item[0] == url:
            func = item[1]
            break 
    if func:
        return func()
    else:
        return '404 not found'
    
if __name__ == '__main__':
    httpd = make_server('', 8000, RunServer)
    print "Serving HTTP on port 8000..."
    httpd.serve_forever()

 

MVC 和 MTV

MVC : model  view controller

            model:模型,表示应用程序核心(比如数据库记录列表),是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。

           view:视图,显示数据(数据库记录),是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的

           controller:控制器,处理输入(写入数据库记录),是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

MTV : model  template  view

            model :负责业务对象和数据库的关系映射(ORM)

           template:负责如何把页面展示给用户(html)

           view:负责业务逻辑,并在适当时调用 model 和 template

 

 

Django

一,创建django程序

1,命令行: django-admin startproject sitename

常用命令:

python manage.py runserver 0.0.0.0             # 启动程序

python manage.py startapp appname           # 新建一个项目

python manage.py syncdb

python manage.py makemigrations              # 把数据库类转换为原生SQL语句

python manage.py migrate                           # 执行SQL语句

二,django程序目录

image

manage.py               # 命令文件

templates                   # 存放静态文件的目录

urls.py                      # URL引导

settings.py               # 主配置文件

models.py                # 创建数据库文件

views.py                  # 主程序文件

admin.py                # 后台管理文件

三,Django流程介绍

四,配置文件

1,URL(urls.py)

from django.conf.urls import url
 
from . import views
 
urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
# 正则匹配
# 可命名的正则
# 即 把正则匹配到的值 /(?P<year>[0-9]{4})/  赋值给 year这个变量名,后面的类似
from django.conf.urls import url
 
from . import views
 
urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

# 注:这里匹配到的所有内容都是字符串类型,这里有多少个正则匹配,在向主程序的时候就需要传入多个个参数

 

from django.conf.urls import include, url
 
urlpatterns = [

    url(r'^community/', include('django_website.aggregator.urls')),
    url(r'^contact/', include('django_website.contact.urls')),

]

# 引入文件,文件跳转,即访问Community 的时候会跳转到 django_website.aggregator.urls 文件处理

 

from django.conf.urls import include, url
from . import views
 
urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/', include([
        url(r'^history/$', views.history),
        url(r'^edit/$', views.edit),
        url(r'^discuss/$', views.discuss),
        url(r'^permissions/$', views.permissions),
    ])),
]

#一次可以定义多个URL,使用url()的方式

 

from django.conf.urls import url
from . import views
 
urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]
#比如匹配到的值为/blog/2005/ 则会向后台传输的参数为 views.year_archive(request, year='2005',foo='bar')

 

# 方法一:

# main.py
from django.conf.urls import include, url
 
urlpatterns = [
    url(r'^blog/', include('inner'), {'blogid': 3}),
]
 
# inner.py
from django.conf.urls import url
from mysite import views
 
urlpatterns = [
    url(r'^archive/$', views.archive),
    url(r'^about/$', views.about),
]

# 方法二:

# main.py
from django.conf.urls import include, url
from mysite import views
 
urlpatterns = [
    url(r'^blog/', include('inner')),
]
 
# inner.py
from django.conf.urls import url
 
urlpatterns = [
    url(r'^archive/$', views.archive, {'blogid': 3}),
    url(r'^about/$', views.about, {'blogid': 3}),
]

# include() 另外deepin方法

# 注:以上URL匹配的方式是从第一条向下,匹配到一条之后就不再向下匹配,所以尽量把精确匹配放到上面,模糊匹配放到下面。

2,Views(views.py)

返回一个字符串:

from django.http import HttpResponse
 
def my_view(request):    #request 关键字,必须写这个,后面可以跟参数
    if request.method == 'GET':
        return HttpResponse('result')

返回一个html文档:

from django.shortcuts import render,HttpResponse
 
def test_view(request):
    return render(request,'index.html')
# render 返回html的关键字
def index(request):
    if request.method == 'GET':
        user_infos = [
            {'username1':'name1','age':'age1'},
            {'username2':'name2','age':'age2'},
            {'username3':'name3','age':'age3'},
            {'username4':'name4','age':'age4'},
        ]
        return render(request, 'app01/index.html',{'user_objs':user_infos})
    #user_objs 为字典的键名,在 app01/index 内可以通过 这个名字来访问 user_infos列表内的值 
    else: #post
        return HttpResponse("transfered 100000 to alex....success.")

从数据中取值:

def book(request):
    if request.method == 'POST':
        print(request.POST)
        book_name = request.POST.get('name')

        # 从前端取值(单个数据)
        publisher_id = request.POST.get('publisher_id')
        print('==>',request.POST.get('author_ids'))
        author_ids = request.POST.getlist('author_ids')
        # getlist 多个值 列表的形式
        #print(dir( request.POST))

        print(book_name,publisher_id,author_ids)
        new_book = models.Book(
            name=book_name,
            publisher_id = publisher_id,
            publish_date = '2016-05-22'
        )
        new_book.save()
        #保存数据
        new_book.authors.add(*author_ids)
        # 写入数据库
        #new_book.authors.add(1,2,3,4)
    books = models.Book.objects.all()
    #从数据中取值所有数据,Book 为表名
    publisher_list = models.Publisher.objects.all()
    author_list = models.Author.objects.all()
    return render(request,'app01/book.html',{'books':books,
                                                 'publishers':publisher_list,
                                                 'authors':author_list
                                                 })
    #以字典的方式返回给前端页面

 

3,数据库(settings.py)

# 文件形式
DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.sqlite3',

        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

    }

}
#数据库形式
DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',
    'USER': 'root',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}

在settings中配置当前APP,不然Django无法找到自定义的simple_tag

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',    #新创建的APPname
)

 

五:数据库操作说明

字段说明(下面会用到):

  • AutoField:自增列 = int(11) , 如果没有的话,默认会生成一个名称为id的列,如果要显示自定义的自增列,必须将给列设置为主键 primary_key=True
  • CharField:字符串字段,必须使用 max_length 参数来限制字符串长度
  • BooleanField:布尔类型=tinyint(1) ,不能为空 Blank=True
  • ComaSepararedIntegerField:用逗号分割的数字=varchar,继承CharField,必须使用 max_lenght 参数
  • DateField:日期类型 date,对于参数 auto_now=True 每次更新都会更新这个时间。auto_now_add 则只有第一次创建添加,之后的更新不再改变
  • DateTimeField:日期类型 datetime 同DateField参数
  • Decimal: 十进制小数类型=decimal,必须指定整数位 max_digits和 小数位 decimal_places
  • EmailFiled:字符串类型(正则表达邮箱)=varchar,对字符串进行正则匹配
  • FloatFiled:浮点类型=double
  • IntegeFiled:整型
  • BigIntegerField:长整型
      integer_field_ranges = {
          'SmallIntegerField': (-32768, 32767),
          'IntegerField': (-2147483648, 2147483647),
          'BigIntegerField': (-9223372036854775808, 9223372036854775807),
          'PositiveSmallIntegerField': (0, 32767),
          'PositiveIntegerField': (0, 2147483647),
        }
  • IPAddressField:字符串类型(ipv4正则匹配)
  • GenericIPAddressField:字符串类型(ipv4和ipv6是可选的),参数protocol可以是both,ipv4,ipv6,验证时,会根据设置报错
  • NullBooleanField:允许为空的布尔类型
  • PositiveIntegerFiel:正则Integer
  • PositiveSmallIntegerField:正则 samllInteger
  • SlugField:减号,下划线,字母,数字
  • SammllIntegerField:数字,数据库中的字段有:tinyint,smallint,int,bigint
  • TextField:字符串=longtext
  • TimeField:时间 HH:MM[:ss[.uuuu]]
  • URLField:字符串,URL正则匹配
  • BinaryField:二进制
  • ImageField:图片
  • FilePathField:文件

参数说明:

  • null=True    数据库中字段是否可以为空
  • blank=True     Django的Admin添加数据时是否允许为空值
  • primary_key=False    主键,对AutoField 设置主键后,就会代替原来的自增 ID 列
  • auto_now   自动创建,无论添加或修改,都是当前操作的时间
  • auto_now_add   自动创建,永远是创建时的时间
    choices
    GENDER_CHOICE = (
            (u'M', u'Male'),
            (u'F', u'Female'),
        )
    gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
  • max_lenght   最大长度
  • default    默认值
  • verbose_name   Admin中字段的显示名称
  • name|db_column    数据库中的字段名称
  • unique=True    不允许重复
  • db_index=True      数据库索引
  • editable=True       在Admin里是否可编辑
  • error_messages=None   错误提示
  • auto_created=False     自动创建
  • help_text     在Admin中提示帮助信息
  • validators=[]
  • upload-to

表关系:

  • ForeignKey(ColorDic)   一对多
  • OneToOneField(OneModel)   一对一
  • ManyToManyField(Author)   多对多

数据库操作:

  • 增加:创建示例,并调用 save()
  • 更新:1,获取实例,再sava   2 ,update(指定列)
  • 删除: 1, filter().delete()   2, all().delete()
  • 获取: 单个 =get(id-1)   所有 =all()
  • 过滤: filteer(name=’xx’);filter(name_contains=’’);(id_in = [1,2,3]);

                   icontains(大小写无关的LIKE),startswith和endswith, 还有range(SQLBETWEEN查询)'gt', 'in', 'isnull', 'endswith', 'contains', 'lt', 'startswith', 'iendswith', 'icontains','range', 'istartswith'

  • 排序: order_by(“name”)=asc; order_by(“-name”)=desc
  • 返回第n-m条,第n条[0];前两条[0:2]
  • 指定映射:values
  • 数量:counter()
  • 聚合:from django.db.models import Min,Max,Sum objects.all().aggregate(Max('guest_id'))
  • 原始SQL
    cursor = connection.cursor()
    cursor.execute('''SELECT DISTINCT first_name ROM people_person WHERE last_name = %s""", ['Lennon'])
    row = cursor.fetchone()
posted @ 2016-05-12 17:20  binges  阅读(1501)  评论(0编辑  收藏  举报