目錄
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