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

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