冰凍三尺非一日之寒--Django框架【進階篇】

第十九章   Django進階html

 

到目前爲止,當咱們的程序涉及到數據庫相關操做時,咱們通常都會這麼搞:python

  • 建立數據庫,設計表結構和字段
  • 使用 MySQLdb 來鏈接數據庫,並編寫數據訪問層代碼
  • 業務邏輯層去調用數據訪問層執行數據庫操做
import MySQLdb
 
def GetList(sql):
    db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')
    cursor = db.cursor()
    cursor.execute(sql)
    data = cursor.fetchall()
    db.close()
    return data
 
def GetSingle(sql):
    db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')
    cursor = db.cursor()
    cursor.execute(sql)
    data = cursor.fetchone()
    db.close()
    return data

django爲使用一種新的方式,即:關係對象映射(Object Relational Mapping,簡稱ORM)。mysql

  PHP:activerecordgit

  Java:Hibernate 正則表達式

    C#:Entity Frameworksql

django中遵循 Code Frist 的原則,即:根據代碼中定義的類來自動生成數據庫表。數據庫

1、建立表django

一、基本結構json

1 from django.db import models
2    
3 class userinfo(models.Model):
4     name = models.CharField(max_length=30)
5     email = models.EmailField()
6     memo = models.TextField()
 1 一、models.AutoField  自增列 = int(11)
 2   若是沒有的話,默認會生成一個名稱爲 id 的列,若是要顯示的自定義一個自增列,必須將給列設置爲主鍵 primary_key=True。
 3 2、models.CharField  字符串字段
 4   必須 max_length 參數
 5 三、models.BooleanField  布爾類型=tinyint(1)
 6   不能爲空,Blank=True
 7 四、models.ComaSeparatedIntegerField  用逗號分割的數字=varchar
 8   繼承CharField,因此必須 max_lenght 參數
 9 5、models.DateField  日期類型 date
10   對於參數,auto_now = True 則每次更新都會更新這個時間;auto_now_add 則只是第一次建立添加,以後的更新再也不改變。
11 6、models.DateTimeField  日期類型 datetime
12   同DateField的參數
13 七、models.Decimal  十進制小數類型 = decimal
14   必須指定整數位max_digits和小數位decimal_places
15 八、models.EmailField  字符串類型(正則表達式郵箱) =varchar
16   對字符串進行正則表達式
17 九、models.FloatField  浮點類型 = double
18 10、models.IntegerField  整形
19 11、models.BigIntegerField  長整形
20   integer_field_ranges = {
21     'SmallIntegerField': (-32768, 32767),
22     'IntegerField': (-2147483648, 2147483647),
23     'BigIntegerField': (-9223372036854775808, 9223372036854775807),
24     'PositiveSmallIntegerField': (0, 32767),
25     'PositiveIntegerField': (0, 2147483647),
26   }
27 12、models.IPAddressField  字符串類型(ip4正則表達式)
28 13、models.GenericIPAddressField  字符串類型(ip4和ip6是可選的)
29   參數protocol能夠是:both、ipv四、ipv6
30   驗證時,會根據設置報錯
31 14、models.NullBooleanField  容許爲空的布爾類型
32 15、models.PositiveIntegerFiel  正Integer
33 16、models.PositiveSmallIntegerField  正smallInteger
34 17、models.SlugField  減號、下劃線、字母、數字
35 18、models.SmallIntegerField  數字
36   數據庫中的字段有:tinyint、smallint、int、bigint
37 1九、models.TextField  字符串=longtext
38 20、models.TimeField  時間 HH:MM[:ss[.uuuuuu]]
39 21、models.URLField  字符串,地址正則表達式
40 22、models.BinaryField  二進制
41 23、models.ImageField   圖片
42 2四、models.FilePathField 文件
View Code

二、連表結構session

  • 一對多:models.ForeignKey(其餘表)
  • 多對多:models.ManyToManyField(其餘表)
  • 一對一:models.OneToOneField(其餘表)

應用場景:

  • 一對多:當一張表中建立一行數據時,有一個單選的下拉框(能夠被重複選擇)
    例如:建立用戶信息時候,須要選擇一個用戶類型【普通用戶】【金牌用戶】【鉑金用戶】等。
  • 多對多:在某表中建立一行數據是,有一個能夠多選的下拉框
    例如:建立用戶信息,須要爲用戶指定多個愛好
  • 一對一:在某表中建立一行數據時,有一個單選的下拉框(下拉框中的內容被用過一次就消失了
    例如:原有含10列數據的一張表保存相關信息,通過一段時間以後,10列沒法知足需求,須要爲原來的表再添加5列數據

2、操做表

一、基本操做

 1  2     #
 3     # models.Tb1.objects.create(c1='xx', c2='oo')  增長一條數據,能夠接受字典類型數據 **kwargs
 4 
 5     # obj = models.Tb1(c1='xx', c2='oo')
 6     # obj.save()
 7 
 8     #
 9     #
10     # models.Tb1.objects.get(id=123)         # 獲取單條數據,不存在則報錯(不建議)
11     # models.Tb1.objects.all()               # 獲取所有
12     # models.Tb1.objects.filter(name='seven') # 獲取指定條件的數據
13 
14     #
15     #
16     # models.Tb1.objects.filter(name='seven').delete() # 刪除指定條件的數據
17 
18     #
19     # models.Tb1.objects.filter(name='seven').update(gender='0')  # 將指定條件的數據更新,均支持 **kwargs
20     # obj = models.Tb1.objects.get(id=1)
21     # obj.c1 = '111'
22     # obj.save()                                                 # 修改單條數據
View Code

二、進階操做(了不得的雙下劃線)

利用雙下劃線將字段和對應的操做鏈接起來

 1 # 獲取個數
 2     #
 3     # models.Tb1.objects.filter(name='seven').count()
 4 
 5     # 大於,小於
 6     #
 7     # models.Tb1.objects.filter(id__gt=1)              # 獲取id大於1的值
 8     # models.Tb1.objects.filter(id__lt=10)             # 獲取id小於10的值
 9     # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 獲取id大於1 且 小於10的值
10 
11     # in
12     #
13     # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 獲取id等於十一、2二、33的數據
14     # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
15 
16     # contains
17     #
18     # models.Tb1.objects.filter(name__contains="ven")
19     # models.Tb1.objects.filter(name__icontains="ven") # icontains大小寫不敏感
20     # models.Tb1.objects.exclude(name__icontains="ven")
21 
22     # range
23     #
24     # models.Tb1.objects.filter(id__range=[1, 2])   # 範圍bettwen and
25 
26     # 其餘相似
27     #
28     # startswith,istartswith, endswith, iendswith,
29 
30     # order by
31     #
32     # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
33     # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc
34 
35     # limit 、offset
36     #
37     # models.Tb1.objects.all()[10:20]
38 
39     # group by
40     from django.db.models import Count, Min, Max, Sum
41     # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
42     # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
43 
44 進階操做

三、連表操做(了不得的雙下劃線)

利用雙下劃線和 _set 將表之間的操做鏈接起來

class UserProfile(models.Model):
    user_info = models.OneToOneField('UserInfo')
    username = models.CharField(max_length=64)
    password = models.CharField(max_length=64)

    def __unicode__(self):
        return self.username


class UserInfo(models.Model):
    user_type_choice = (
        (0, u'普通用戶'),
        (1, u'高級用戶'),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    name = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    address = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name


class UserGroup(models.Model):

    caption = models.CharField(max_length=64)

    user_info = models.ManyToManyField('UserInfo')

    def __unicode__(self):
        return self.caption


class Host(models.Model):
    hostname = models.CharField(max_length=64)
    ip = models.GenericIPAddressField()
    user_group = models.ForeignKey('UserGroup')

    def __unicode__(self):
        return self.hostname

表結構實例
 1 user_info_obj = models.UserInfo.objects.filter(id=1).first()
 2 print user_info_obj.user_type
 3 print user_info_obj.get_user_type_display()
 4 print user_info_obj.userprofile.password
 5  
 6 user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
 7 print user_info_obj.keys()
 8 print user_info_obj.values()
 9 
10 一對一操做
一對一操做
一對多相似一對一
1、搜索條件使用 __ 鏈接 二、獲取值時使用 . 鏈接
 1 user_info_obj = models.UserInfo.objects.get(name=u'武沛齊')
 2 user_info_objs = models.UserInfo.objects.all()
 3  
 4 group_obj = models.UserGroup.objects.get(caption='CEO')
 5 group_objs = models.UserGroup.objects.all()
 6  
 7 # 添加數據
 8 #group_obj.user_info.add(user_info_obj)
 9 #group_obj.user_info.add(*user_info_objs)
10  
11 # 刪除數據
12 #group_obj.user_info.remove(user_info_obj)
13 #group_obj.user_info.remove(*user_info_objs)
14  
15 # 添加數據
16 #user_info_obj.usergroup_set.add(group_obj)
17 #user_info_obj.usergroup_set.add(*group_objs)
18  
19 # 刪除數據
20 #user_info_obj.usergroup_set.remove(group_obj)
21 #user_info_obj.usergroup_set.remove(*group_objs)
22  
23 # 獲取數據
24 #print group_obj.user_info.all()
25 #print group_obj.user_info.all().filter(id=1)
26  
27 # 獲取數據
28 #print user_info_obj.usergroup_set.all()
29 #print user_info_obj.usergroup_set.all().filter(caption='CEO')
30 #print user_info_obj.usergroup_set.all().filter(caption='DBA')
31 
32 多對多操做
多對多操做
 
 1 # F 使用查詢條件的值
 2     #
 3     # from django.db.models import F
 4     # models.Tb1.objects.update(num=F('num')+1)
 5 
 6     # Q 構建搜索條件
 7     from django.db.models import Q
 8     # con = Q()
 9     #
10     # q1 = Q()
11     # q1.connector = 'OR'
12     # q1.children.append(('id', 1))
13     # q1.children.append(('id', 10))
14     # q1.children.append(('id', 9))
15     #
16     # q2 = Q()
17     # q2.connector = 'OR'
18     # q2.children.append(('c1', 1))
19     # q2.children.append(('c1', 10))
20     # q2.children.append(('c1', 9))
21     #
22     # con.add(q1, 'AND')
23     # con.add(q2, 'AND')
24     #
25     # models.Tb1.objects.filter(con)
26 
27     #
28     # from django.db import connection
29     # cursor = connection.cursor()
30     # cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])
31     # row = cursor.fetchone()
32 
33 其餘操做
其餘操做

注意:xx_set中的【_set】是多對多中的固定搭配

擴展:

a、自定義上傳

1 def upload_file(request):
2     if request.method == "POST":
3         obj = request.FILES.get('fafafa')
4         f = open(obj.name, 'wb')
5         for chunk in obj.chunks():
6             f.write(chunk)
7         f.close()
8     return render(request, 'file.html')

b、Form上傳文件實例

class FileForm(forms.Form): ExcelFile = forms.FileField()

from django.db import models class UploadFile(models.Model): userid = models.CharField(max_length = 30) file = models.FileField(upload_to = './upload/') date = models.DateTimeField(auto_now_add=True)
 
複製代碼
def UploadFile(request): uf = AssetForm.FileForm(request.POST,request.FILES) if uf.is_valid(): upload = models.UploadFile() upload.userid = 1 upload.file = uf.cleaned_data['ExcelFile'] upload.save() print upload.file
 

django中的Form通常有兩種功能:

 
  • 輸入html
  • 驗證用戶輸入
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 import re
 4 from django import forms
 5 from django.core.exceptions import ValidationError
 6 
 7 
 8 def mobile_validate(value):
 9     mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
10     if not mobile_re.match(value):
11         raise ValidationError('手機號碼格式錯誤')
12 
13 
14 class PublishForm(forms.Form):
15 
16     user_type_choice = (
17         (0, u'普通用戶'),
18         (1, u'高級用戶'),
19     )
20 
21     user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
22                                                                   attrs={'class': "form-control"}))
23 
24     title = forms.CharField(max_length=20,
25                             min_length=5,
26                             error_messages={'required': u'標題不能爲空',
27                                             'min_length': u'標題最少爲5個字符',
28                                             'max_length': u'標題最多爲20個字符'},
29                             widget=forms.TextInput(attrs={'class': "form-control",
30                                                           'placeholder': u'標題5-20個字符'}))
31 
32     memo = forms.CharField(required=False,
33                            max_length=256,
34                            widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'詳細描述', 'rows': 3}))
35 
36     phone = forms.CharField(validators=[mobile_validate, ],
37                             error_messages={'required': u'手機不能爲空'},
38                             widget=forms.TextInput(attrs={'class': "form-control",
39                                                           'placeholder': u'手機號碼'}))
40 
41     email = forms.EmailField(required=False,
42                             error_messages={'required': u'郵箱不能爲空','invalid': u'郵箱格式錯誤'},
43                             widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'}))
44 
45 Form
View Code
def publish(request):
    ret = {'status': False, 'data': '', 'error': '', 'summary': ''}
    if request.method == 'POST':
        request_form = PublishForm(request.POST)
        if request_form.is_valid():
            request_dict = request_form.clean()
            print request_dict
            ret['status'] = True
        else:
            error_msg = request_form.errors.as_json()
            ret['error'] = json.loads(error_msg)
    return HttpResponse(json.dumps(ret))

View

擴展:ModelForm

在使用Model和Form時,都須要對字段進行定義並指定類型,經過ModelForm則能夠省去From中字段的定義

 1 class AdminModelForm(forms.ModelForm):
 2       
 3     class Meta:
 4         model = models.Admin
 5         #fields = '__all__'
 6         fields = ('username', 'email')
 7           
 8         widgets = {
 9             'email' : forms.PasswordInput(attrs={'class':"alex"}),
10         }

 

筆記:一、Django請求生命週期        -> URL對應關係(匹配) -> 視圖函數 -> 返回用戶字符串        -> URL對應關係(匹配) -> 視圖函數 -> 打開一個HTML文件,讀取內容            二、建立django projcet        django-admin startproject mysite                ..                mysite            mysite                - 配置文件                - url.py                - settings.py                    cd mysite        python manage.py startapp cmdb                mysite            mysite                - 配置文件                - url.py                - settings.py            cmdb                - views.py                - admin.py                - models.py # 建立數據庫表    三、配置                模板路徑        靜態文件路徑        # CSRF            四、編寫程序        a. url.py                        /index/    ->   func                    b. views.py                        def func(request):                # 包含全部的請求數據                ...                return HttpResponse('字符串')                return render(request, 'index.html', {''})                retrun redirect('URL')                        c. 模板語言            return render(request, 'index.html', {'li': [11,22,33]})                        {% for item in li %}                <h1>{{item}}</h1>            {% endfor %}                                    ***********  索引用點 **********            <h2> {{item.0 }} </h2>1、路由系統,URL    一、url(r'^index/', views.index),           url(r'^home/', views.Home.as_view()),    二、url(r'^detail-(\d+).html', views.detail),      三、url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail)              PS:            def detail(request, *args,**kwargs):                pass           實戰:            a.                 url(r'^detail-(\d+)-(\d+).html', views.detail),                                def func(request, nid, uid):                                        pass                            def func(request, *args):                    args = (2,9)                                                        def func(request, *args, **kwargs):                    args = (2,9)                   b.                 url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail)                                def func(request, nid, uid):                    pass                                    def funct(request, **kwargs):                    kwargs = {'nid': 1, 'uid': 3}                                    def func(request, *args, **kwargs):                    args = (2,9)    四、 name                對URL路由關係進行命名, ***** 之後能夠根據此名稱生成本身想要的URL *****                url(r'^asdfasdfasdf/', views.index, name='i1'),        url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'),        url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),                                def func(request, *args, **kwargs):            from django.urls import reverse                        url1 = reverse('i1')                              # asdfasdfasdf/            url2 = reverse('i2', args=(1,2,))                 # yug/1/2/            url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/                        xxx.html                        {% url "i1" %}               # asdfasdfasdf/            {% url "i2" 1 2 %}           # yug/1/2/            {% url "i3" pid=1 nid=9 %}   # buy/1/9/                注:            # 當前的URL            request.path_info     五、多級路由                project/urls.py            from django.conf.urls import url,include            from django.contrib import admin            urlpatterns = [                url(r'^cmdb/', include("app01.urls")),                url(r'^monitor/', include("app02.urls")),            ]                    app01/urls.py            from django.conf.urls import url,include            from django.contrib import admin            from app01 import views            urlpatterns = [                url(r'^login/', views.login),            ]                    app02/urls.py            from django.conf.urls import url,include            from django.contrib import admin            from app02 import views            urlpatterns = [                url(r'^login/', views.login),            ]        六、默認值(欠)        七、命名空間(欠)        2、視圖    一、獲取用戶請求數據        request.GET        request.POST        request.FILES        PS:            GET:獲取數據                            POST:提交數據                二、checkbox等多選的內容        request.POST.getlist()    三、上傳文件        # 上傳文件,form標籤作特殊設置        obj = request.FILES.get('fafafa')        obj.name        f = open(obj.name, mode='wb')        for item in obj.chunks():            f.write(item)        f.close()        四、FBV & CBV       function base view               url.py            index -> 函數名                    view.py            def 函數(request):                ...        ====》        /index/ -> 函數名                    /index/ -> 類                ====》                建議:二者都用            五、裝飾器        欠    3、模板        4、ORM操做    select * from tb where id > 1    # 對應關係    models.tb.objects.filter(id__gt=1)    models.tb.objects.filter(id=1)    models.tb.objects.filter(id__lt=1)        建立類        a. 先寫類        from django.db import models        # app01_userinfo        class UserInfo(models.Model):            # id列,自增,主鍵            # 用戶名列,字符串類型,指定長度            username = models.CharField(max_length=32)            password = models.CharField(max_length=64)            b. 註冊APP        INSTALLED_APPS = [            'django.contrib.admin',            'django.contrib.auth',            'django.contrib.contenttypes',            'django.contrib.sessions',            'django.contrib.messages',            'django.contrib.staticfiles',            'app01',        ]    c. 執行命令        python manage.py  makemigrations        python manage.py  migrate            d. ********** 注意 ***********        Django默認使用MySQLdb模塊連接MySQL        主動修改成pymysql,在project同名文件夾下的__init__文件中添加以下代碼便可:            import pymysql            pymysql.install_as_MySQLdb()        1. 根據類自動建立數據庫表        # app下的models.py            python manage.py  makemigrations        python manage.py  migrate                        字段:            字符串類型                                    數字                                    時間                                    二進制                        自增(primary_key=True)                    字段的參數:            null               -> db是否能夠爲空            default            -> 默認值            primary_key        -> 主鍵            db_column          -> 列名            db_index           -> 索引            unique               -> 惟一索引            unique_for_date    ->             unique_for_month            unique_for_year            auto_now           -> 建立時,自動生成時間            auto_now_add       -> 更新時,自動更新爲當前時間                            # obj = UserGroup.objects.filter(id=1).update(caption='CEO')                # obj = UserGroup.objects.filter(id=1).first()                # obj.caption = "CEO"                # obj.save()                            choices              -> django admin中顯示下拉框,避免連表查詢            blank             -> django admin是否能夠爲空            verbose_name      -> django admin顯示字段中文            editable          -> django admin是否能夠被編輯            error_messages    -> 錯誤信息欠            help_text         -> django admin提示            validators          -> django form ,自定義錯誤信息(欠)                                    建立 Django 用戶:python manage.py createsuperuser                                                    2. 根據類對數據庫表中的數據進行各類操做            一對多:                    a. 外檢            b.                 外鍵字段_id            c.                models.tb.object.create(name='root', user_group_id=1)                            d.                                 userlist = models.tb.object.all()                for row in userlist:                    row.id                    row.user_group_id                    row.user_group.caption
相關文章
相關標籤/搜索