Django重要知識點

1、Django獲取多個數據

在我們的view.py中獲取前端form表單發來的一個數據比較簡單,比如text、radio、password等

v = request.POST.get("username")

獲取多個數據,比如checkbox、select

v = request.POST.getlist("favor")

2、Django文件上傳

前端代碼

<form action="" method="post" enctype="multipart/form-data">
	<input type="file" name="fname" />
	<input type="submit" value="提交" />
</form>

view.py

obj = request.FILES.get("fname")
# obj.name 文件名
# obj.size 文件大小

print(obj, type(obj))

f = open(obj.name, "wb") # 當前路徑新建一個文件,名叫源文件的名字
for i in obj.chunks(): # 本地下載,chunks生成器迭代器的知識點
	f.write(i)
f.close()

3、CBV和FBV

FBV:function base view
就是經常用的,urls.py中請求對應views.py中的函數

urls.py
	path('index/', views.index),
	
views.py
	def index(request):
		if	request.method == "POST":
    		return render(request, 'index.html')
    	elif request.method == "GET":
    		return render(request, 'index.html')

CBV:class base view
urls.py中請求對應views.py中的類,和FBV不同點就是,不需要自己去判斷提交方式是哪一種了
提交方式有:[‘get’, ‘post’, ‘put’, ‘patch’, ‘delete’, ‘head’, ‘options’, ‘trace’]

urls.py
	path('home/', views.Home.as_view()),
	
views.py
	from django.views import View
	class Home(View):
		# 請求來了,先調用dispatch,基於反射找到相應的提交方式
		#這樣重寫父類的dispatch可以定製功能
		def dispatch(self, request, *args, **kwargs):
	       #調用父類的dispatch
	        print('before')
	        result = super(Home, self).dispatch(request, *args, **kwargs)
	        print('after')
	        return result

	    def get(self, request):
	        print(request.method)
	        return render(request, 'home.html')
	
	    def post(self, request):
	        print(request.method)
	        return render(request, 'home.html')

4、DjangoORM

1.創建基本類型以及生成數據庫結構

創建類
1、根據類自動創建數據庫表
在app下的models.py

from django.db import models

# Create your models here.

#app01_userinfo
class UserInfo(models.Model):
    #  隱含的,自動創建id列,自增,主鍵
    # 用戶名列、字符串類型、指定長度
    # 字段:字符串、數字、時間、二進制、自增(primary_key)
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)

Django提供了大量的字段,其中大部分字段都是給Django自帶的後臺管理系統使用的

字段
AutoField(Field)
   - int自增列,必須填入參數 primary_key=True

BigAutoField(AutoField)
   - bigint自增列,必須填入參數 primary_key=True

   注:當model中如果沒有自增列,則自動會創建一個列名爲id的列
   from django.db import models

   class UserInfo(models.Model):
       # 自動創建一個列名爲id的且爲自增的整數列
       username = models.CharField(max_length=32)

   class Group(models.Model):
       # 自定義自增列
       nid = models.AutoField(primary_key=True)
       name = models.CharField(max_length=32)

SmallIntegerField(IntegerField):
   - 小整數 -32768 ~ 32767

PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
   - 正小整數 0 ~ 32767
IntegerField(Field)
   - 整數列(有符號的) -2147483648 ~ 2147483647

PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
   - 正整數 0 ~ 2147483647

BigIntegerField(IntegerField):
   - 長整型(有符號的) -9223372036854775808 ~ 9223372036854775807

自定義無符號整數字段

   class UnsignedIntegerField(models.IntegerField):
       def db_type(self, connection):
           return 'integer UNSIGNED'

   PS: 返回值爲字段在數據庫中的屬性,Django字段默認的值爲:
       'AutoField': 'integer AUTO_INCREMENT',
       'BigAutoField': 'bigint AUTO_INCREMENT',
       'BinaryField': 'longblob',
       'BooleanField': 'bool',
       'CharField': 'varchar(%(max_length)s)',
       'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
       'DateField': 'date',
       'DateTimeField': 'datetime',
       'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
       'DurationField': 'bigint',
       'FileField': 'varchar(%(max_length)s)',
       'FilePathField': 'varchar(%(max_length)s)',
       'FloatField': 'double precision',
       'IntegerField': 'integer',
       'BigIntegerField': 'bigint',
       'IPAddressField': 'char(15)',
       'GenericIPAddressField': 'char(39)',
       'NullBooleanField': 'bool',
       'OneToOneField': 'integer',
       'PositiveIntegerField': 'integer UNSIGNED',
       'PositiveSmallIntegerField': 'smallint UNSIGNED',
       'SlugField': 'varchar(%(max_length)s)',
       'SmallIntegerField': 'smallint',
       'TextField': 'longtext',
       'TimeField': 'time',
       'UUIDField': 'char(32)',

BooleanField(Field)
   - 布爾值類型

NullBooleanField(Field):
   - 可以爲空的布爾值

CharField(Field)
   - 字符類型
   - 必須提供max_length參數, max_length表示字符長度

TextField(Field)
   - 文本類型

EmailField(CharField):
   - 字符串類型,Django Admin以及ModelForm中提供驗證機制

GenericIPAddressField(Field)
   - 字符串類型,Django Admin以及ModelForm中提供驗證 Ipv4和Ipv6
   - 參數:
       protocol,用於指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
       unpack_ipv4, 如果指定爲True,則輸入::ffff:192.0.2.1時候,可解析爲192.0.2.1,開啓刺功能,需要protocol="both"

URLField(CharField)
   - 字符串類型,Django Admin以及ModelForm中提供驗證 URL

SlugField(CharField)
   - 字符串類型,Django Admin以及ModelForm中提供驗證支持 字母、數字、下劃線、連接符(減號)

CommaSeparatedIntegerField(CharField)
   - 字符串類型,格式必須爲逗號分割的數字

UUIDField(Field)
   - 字符串類型,Django Admin以及ModelForm中提供對UUID格式的驗證

FilePathField(Field)
   - 字符串,Django Admin以及ModelForm中提供讀取文件夾下文件的功能
   - 參數:
           path,                      文件夾路徑
           match=None,                正則匹配
           recursive=False,           遞歸下面的文件夾
           allow_files=True,          允許文件
           allow_folders=False,       允許文件夾

FileField(Field)
   - 字符串,路徑保存在數據庫,文件上傳到指定目錄
   - 參數:
       upload_to = ""      上傳文件的保存路徑
       storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage

ImageField(FileField)
   - 字符串,路徑保存在數據庫,文件上傳到指定目錄
   - 參數:
       upload_to = ""      上傳文件的保存路徑
       storage = None      存儲組件,默認django.core.files.storage.FileSystemStorage
       width_field=None,   上傳圖片的高度保存的數據庫字段名(字符串)
       height_field=None   上傳圖片的寬度保存的數據庫字段名(字符串)

DateTimeField(DateField)
   - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

DateField(DateTimeCheckMixin, Field)
   - 日期格式      YYYY-MM-DD

TimeField(DateTimeCheckMixin, Field)
   - 時間格式      HH:MM[:ss[.uuuuuu]]

DurationField(Field)
   - 長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值爲datetime.timedelta類型

FloatField(Field)
   - 浮點型

DecimalField(Field)
   - 10進制小數
   - 參數:
       max_digits,小數總長度
       decimal_places,小數位長度

BinaryField(Field)
   - 二進制類型
參數
null                數據庫中字段是否可以爲空
db_column           數據庫中字段的列名
db_tablespace
default             數據庫中字段的默認值
primary_key         數據庫中字段是否爲主鍵
db_index            數據庫中字段是否可以建立索引
unique              數據庫中字段是否可以建立唯一索引
unique_for_date     數據庫中字段【日期】部分是否可以建立唯一索引
unique_for_month    數據庫中字段【月】部分是否可以建立唯一索引
unique_for_year     數據庫中字段【年】部分是否可以建立唯一索引

auto_now			創建時,自動生成時間
auto_now_add		更新時,自動更新時間
					如:
					ctime = models.DateTimeField(auto_now_add=True, null=True)
    				uptime = models.DateTimeField(auto_now=True, null=True)
    				自動更新時:1更新時間不會發生變化,2有效,所以要用第二種
    				寫法一:
    				obj = UserGroup.objects.filter(id=1).update(caption="CEO")
    				寫法二:
    				obj = UserGroup.objects.filter(id=1).first()
    				obj.caption="CEO"
    				obj.save()
    	

verbose_name        Admin中顯示的字段名稱
blank               Admin中是否允許用戶輸入爲空
editable            Admin中是否可以編輯
help_text           Admin中該字段的提示信息
choices             Admin中顯示選擇框的內容,用不變動的數據放在內存中從而避免跨表操作
                    如:
                    user_type_choices = (
				        (1, '超級用戶'),
				        (1, '普通用戶'),
				        (1, '普普通用戶'),
				    )
				    user_type_id = models.IntegerField(choices=user_type_choices, default=1)

error_messages      自定義錯誤信息(字典類型),從而定製想要顯示的錯誤信息;
                    字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                    如:{'null': "不能爲空.", 'invalid': '格式錯誤'}

validators          自定義錯誤驗證(列表類型),從而定製想要的驗證規則
                    from django.core.validators import RegexValidator
                    from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
                    MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                    如:
                       test = models.CharField(
                           max_length=32,
                           error_messages={
                               'c1': '優先錯信息1',
                               'c2': '優先錯信息2',
                               'c3': '優先錯信息3',
                           },
                           validators=[
                               RegexValidator(regex='root_\d+', message='錯誤了', code='c1'),
                               RegexValidator(regex='root_112233\d+', message='又錯誤了', code='c2'),
                               EmailValidator(message='又錯誤了', code='c3'), ]
                       )

寫好類之後,查看settings.py中的app是否註冊了,如果註冊,執行命令,生成數據庫表

#django生成表結構、修改表結構
python3 manage.py makemigrations
python3 manage.py migrate

2、根據類對數據庫表中的數據進行操作

# 創建
    # 1、
    models.UserInfo.objects.create(username='root', password='123')
    #models.UserGroup.objects.create(caption="dba")
    
    # 2、
    dic = {'username': 'test', 'password': '123'}
    models.UserInfo.objects.create(**dic)

    # 3、
    obj = models.UserInfo(username='severen', password="123")
    obj.save()

    # 查
    result = models.UserInfo.objects.all()
    result是一個QuerySet類型,這個類型是Django提供的,我們去理解的就話,就當它是一個列表即可,列表內的元素是UserInfo的對象
    result = models.UserInfo.objects.filter(username='root')
    result = models.UserInfo.objects.filter(username='root', password='123')
    for row in result:
        print(row.id, row.username, row.password)
	obj = models.UserInfo.objects.filter(id=nid).first()
    # 取單條數據,如果不存在,就直接報錯
    # models.UserInfo.objects.get(id=nid)

    # 刪除
    models.UserInfo.objects.all().delete()
    models.UserInfo.objects.filter(id=4).delete()

    # 更新
    models.UserInfo.objects.all().update(password='666')
    # gte -> 大於等於;lte -> 小於等於
    models.UserInfo.objects.filter(id__gt=1).update(password='666') # id > 1

2.外鍵操作

# UserInfo表中的user_group字段關聯UserGroup表的主鍵,建立外鍵關係
# 數據庫裏面會自動生成字段名user_group_id
user_group = models.ForeignKey("UserGroup", to_field='uid', default=1, on_delete=models.CASCADE) # 如果沒有指定to_field字段,默認和關聯表的主鍵關聯

在進行操作的時候,可以取到obj.user_group和obj.user_group_id
obj.user_group是一個對象
obj.user_group_id是數值

3.獲取單表單數據的三種方式

# way one
v1 = models.Business.objects.all()
# QuerySet, 內部元素是對象
# [obj(id, caption, code), obj, obj...]

# way two
v2 = models.Business.objects.all().values('id', 'caption')
# QuerySet, 內部元素是字典
# [{'id':1, 'caption':'運維部'},{},{}...]

# way three
v3 = models.Business.objects.all().values_list('id', 'caption')
# QuerySet, 內部元素是元組
# [(1, '運維部'),(2, '開發'),()...]
<h1>業務線列表(對象)</h1>
<ul>
    {% for row in v1 %}
        <li>
            {{row.id}}-{{row.caption}}-{{row.code}}
        </li>
    {% endfor %}
</ul>
<h1>業務線列表(字典)</h1>
<ul>
    {% for row in v2 %}
        <li>
            {{row.id}}-{{row.caption}}
        </li>
    {% endfor %}
</ul>
<h1>業務線列表(元組)</h1>
<ul>
    {% for row in v3 %}
        <li>
            {{row.0}}-{{row.1}}
        </li>
    {% endfor %}
</ul>

4.獲取一對多數據的的三種方式

# way 1
v1 = models.Host.objects.all()

# 雙下劃線 way 2
v2 = models.Host.objects.filter(nid__gt=0).values('nid', 'hostname', 'ip', 'port', 'b_id', 'b__caption')
for row in v2:
    print(row["nid"],row["hostname"],row["ip"],row["port"],row["b_id"],row["b__caption"])
    
# way 3
v3 = models.Host.objects.filter(nid__gt=0).values_list('nid', 'hostname', 'ip', 'port', 'b_id', 'b__caption')
<h1>主機列表(對象)</h1>
<div>
    <input id='add_host' type='button' value='添加' />
</div>
<table border='1'>
    <thead>
        <tr>
            <th>序號</th>
            <th>主機名</th>
            <th>IP</th>
            <th>端口</th>
            <th>業務線名稱</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v1 %}
            <tr hid='{{row.nid}}' bid='{{row.b_id}}'>
                <td>{{forloop.counter}}</td> <!--forloop.counter: for循環的計數器,從1開始,循環一次記+1,counter0:從0開始, revcounter, revcounter0:反轉, last, first:是否是最後一個,第一個-->
                <td>{{row.hostname}}</td>
                <td>{{row.ip}}</td>
                <td>{{row.port}}</td>
                <td>{{row.b.caption}}</td>
                <td>
                    <a class='edit'>編輯</a>|<a class='delete'>刪除</a>
                </td>
            </tr>
        {% endfor %}
    </tbody>
</table>
<h1>主機列表(字典)</h1>
<table border='1'>
    <thead>
        <tr>
            <th>主機名</th>
            <th>IP</th>
            <th>端口</th>
            <th>業務線名稱</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v2 %}
            <tr hid='{{row.nid}}' bid='{{row.b_id}}'>
                <td>{{row.hostname}}</td>
                <td>{{row.ip}}</td>
                <td>{{row.port}}</td>
                <td>{{row.b__caption}}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>
<h1>主機列表(元組)</h1>
<table border='1'>
    <thead>
        <tr>
            <th>主機名</th>
            <th>IP</th>
            <th>端口</th>
            <th>業務線名稱</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v3 %}
            <tr hid='{{row.0}}' bid='{{row.4}}'>
                <td>{{row.1}}</td>
                <td>{{row.2}}</td>
                <td>{{row.3}}</td>
                <td>{{row.5}}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

5.多對多關係

創建多對多

way1:自定義關係表
優點:想生成多少列數據就多少列
缺點:需要自己寫第三張表

class Host(models.Model):
    nid = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=32, db_index=True) # db_index: 索引
    ip = models.GenericIPAddressField(protocol="both", db_index=True) # protocol: 支持ipv4還是ipv6
    port = models.IntegerField()
    b = models.ForeignKey("Business", to_field="id", on_delete=models.CASCADE)

class Application(models.Model):
    name = models.CharField(max_length=32)

class HostToApp(models.Model):
    hobj = models.ForeignKey(to="Host", to_field="nid", on_delete=models.CASCADE)
    aobj = models.ForeignKey(to='Application', to_field='id', on_delete=models.CASCADE)

way2:自動創建關係表
優點:不要自己寫第三張表,自動生成
缺點:最多生成三列數據類型

class Host(models.Model):
    nid = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=32, db_index=True) # db_index: 索引
    ip = models.GenericIPAddressField(protocol="both", db_index=True) # protocol: 支持ipv4還是ipv6
    port = models.IntegerField()
    b = models.ForeignKey("Business", to_field="id", on_delete=models.CASCADE)

class Application(models.Model):
    name = models.CharField(max_length=32)
    r = models.ManyToManyField("Host") # django將自動幫助創建關聯表

對第三張表的數據操作

way1

# 通過類來操作數據庫
obj = models.HostToApp.objects.create(hobj=1, aobj=2)

way2

obj = models.Application.objects.get(id=1)
obj.name

# 添加
obj.r.add(1)
obj.r.add(2)
obj.r.add(3,4,5)
obj.r.add(*[1,2,3,4])

# 刪除
obj.r.remove(1)
obj.r.remove(2,3)
obj.r.remove(*[1,2,3])

# 清空
obj.r.clear()

# 更新
obj.r.set([3,4,5]) # 清空之前的所有,變成我現在設置的這個

# 獲取值
obj.r.all() # 所有相關的主機對象"列表" QuerySet

項目地址:
https://github.com/Stark-Xue/test2
https://github.com/Stark-Xue/test3

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