py一些笔记
定义空数组
a = ['']
b = list()
print(a)
print(b)
------------------------------
a = ['']
b = list()
print(a)
print(b)
print('----------------------------------------')
b.append('java')
b.append('c')
b.append('php')
print(b)
print('----------------------------------------')
b.pop(0)
print(b)
print('----------------------------------------')
b.remove('php')
print(b)
----------------------------------------------------
a = ['']
b = list()
print(a)
print(b)
print('----------------------------------------')
b.append('java')
b.append('c')
b.append('php')
print(b)
# boolean
print('python' in b)
for i in b:
print('值是', i)
其他例子:
a = []
b = list()
print(a)
a.append('python')
print(b)
print('----------------------------------------')
b.append('java')
b.append('c')
b.append('php')
print(b)
a.extend(b)
print(a)
# boolean
print('python' in b)
for i in b:
print('值是', i)
# count用于计算字符在列表里面出现的次数
print(a.count('python'))
print(a.index('php'))
c=['abc','def',';',['aaa'],{'name':'mike'}]
print(c)
字典的学习
# 定义一个字典
a = dict()
b = {}
a = {'name':'杰克','age':19,'address':'shanghai'}
# 添加key-value
a['job'] = 'IT'
a.setdefault('job1', 'edu')
print(a)
print('----------------------------------------------')
#取出key
try:
print(a['job1'])
except KeyError:
print('key error')
finally:
print('一定会执行我这行代码')
print(a.get('job'))
#修改字典的值
a['name'] = '外壳'
print(a)
#修改字典的值不要用setdefault,setdefault是用来添加key-value值的。对于已存在的key,setdefault无法设置其值
字典学习
a = {}
b = {'name':'mike'}
print(a)
print(b)
# 把b的字典赋值给a
a.update(b)
print("现在的a字典是:",a)
# 把b的字典再次添加到a上面
b.setdefault('age', 14)
a.update(b)
print("现在的a字典是:",a)
# 生成可迭代的对象
print("打印所有的key")
for i in a.keys():
print(i)
print("打印所有的values")
for i in a.values():
print(i)
print("打印字典的key-value键值对,注意返回的是元祖类型")
for i in a.items():
print(i)
# 返回数组类型
list = [i for i in a.keys()]
print(list)
# 删除元素
a.pop('age')
print("现在只有name这个key了",a)
set集合练习
a = set()
print("这是一个set集合:", a)
a.add(1)
print(a)
a.add(2)
print(a)
a.add(1)
print("集合增加重复的元素是加不进去的,比如a集合还是这些元素",a)
b = []
b.append(1)
b.append(2)
b.append(1)
print("列表对于重复的元素依然会增加,不会去重复值", b)
print("列表和集合的区别就是集合的元素是不可重复的,利用这个特性可以去重元素")
print("列表与集合的转化")
c = set(b)
print("现在的c集合是",c)
c = list(c)
print("现在的c列表是",c)
c = sorted(c,reverse=True)
print("现在的c列表反转一下", c)
# 在定义一个d,对d列表进行排序
d = [5,2,4,9,7,3]
print("原来的d列表是",d)
print("对d列表排序一下", sorted(d))
# 定义e列表
e = [5,2,4,9,8,3,6,2,4,9]
e = sorted(list(set(e)),reverse=True)
print("原来的e列表是",e)
print("去重后的e列表是",e)
变量a为空值的代码:
None = '' = 空元祖 = 空列表 = 空字典
while循环
import time
n = 0
while True: # while 1也可以
# 休息一秒钟
time.sleep(1)
print("hello world {}".format(n))
if n == 10:
break
n += 1
一些函数使用
a = ['1',2,3,4,5]
b = [1,2,3,4,5]
c = (1,2,3,4,5)
#print("数据类型不统一会报错",sum(a))
print("列表的总数是:",sum(b))
print("元祖的总数是:",sum(c))
匿名函数
a = lambda x:x+1
print(a(10))
print(a(100))
b = lambda x:x*50
print(b(10))
c = lambda x,y:x*y
print(c(3,8))
实名函数
def print_name(name,address='beijing'):
print("hello {}, wolcome to {}".format(name,address))
print_name('杰克')
def print_name(name,address='beijing'):
print("hello {}, wolcome to {}".format(name,address))
print_name('杰克','Shanghai') # 当我传参时,使用我传参的值。不传参时,直接使用默认值beijing
不定长函数
def print_name(name, *args):
print(args[0],args[1]) # name已经传过去值了,现在还有后面两个参数
print_name('杰克','上海',25)
关键字函数
def print_name(name, *args,**args1): # **args是用来接受字典类型
print(args, args1)
print_name('杰克','上海',25,job='python',age=20)
装饰器应用
def wrap(func):
def inner(*args, **kwargs):
m = args[0]
n = args[1]
if not (type(m) == int and type(n) == int):
return "参数输入错误"
res = func(*args, **kwargs)
return res
return inner
@wrap
def sum1(m, n):
return m+n
value = sum1(10,70)
print(value)
类,例子一
# slef是当前实例本身
class Person:
name = '杰克'
# __init__初始化一些属性
def __init__(self):
self.score = 100
def get_name(self):
return 'Name is {}, score is {}'.format(self.name, self.score)
p = Person()
print(p.name)
print(p.get_name())
传入参数
# slef是当前实例本身
class Person:
name = '杰克'
# __init__初始化一些属性
# 对于公共的参数可以直接写在__init__
def __init__(self, address):
self.score = 100
self.address = address
# 对于其他的可以写个方法参数
def get_name(self, project):
return 'Name is {}, score is {}, project is {}, address is {}'.format(self.name, self.score, project, self.address)
# __init__里面写的初始化的参数可以在实例化对象的时候传进去
p = Person('BeiJing')
print(p.name)
print(p.get_name('python'))
子类继承父类
# slef是当前实例本身
class Person:
name = '杰克'
# __init__初始化一些属性
# 对于公共的参数可以直接写在__init__
def __init__(self, address):
self.score = 100
self.address = address
# 对于其他的可以写个方法参数
def get_name(self, project):
return 'Name is {}, score is {}, project is {}, address is {}'.format(self.name, self.score, project,
self.address)
class SportPerson(Person):
age = 25
def get_age(self):
return 'Name is {}, age is {}'.format(self.name, self.age)
# __init__里面写的初始化的参数可以在实例化对象的时候传进去
# 子类继承父类,子类也要写所有类中的__init__方法的参数
s = SportPerson('Shanghai')
print(s.get_name('python'))
print(s.get_age())
第二个例子:
# slef是当前实例本身
class Person:
name = '杰克'
# __init__初始化一些属性
# 对于公共的参数可以直接写在__init__
def __init__(self, address):
self.score = 100
self.address = address
# 对于其他的可以写个方法参数
def get_name(self, project):
return 'Name is {}, score is {}, project is {}, address is {}'.format(self.name, self.score, project,
self.address)
class SportPerson(Person):
age = 25
def __init__(self):
self.fruit = 'apple'
def get_age(self):
return 'Name is {}, age is {}'.format(self.name, self.age)
# __init__里面写的初始化的参数可以在实例化对象的时候传进去
# 子类继承父类,子类也要写所有类中的__init__方法的参数
s = SportPerson()
print(s.get_age())
多继承的话,如果多个父类含有同名的方法,则以第一个类为主。
实例化与类方法,静态方法,上面的方法都是实例化,下面这个是类方法
# slef是当前实例本身
class Person:
name = '杰克'
# __init__初始化一些属性
# 对于公共的参数可以直接写在__init__
def __init__(slef, address):
slef.score = 100
slef.address = address
# 注意下面的cls.score不能在__init__里面出现使用,也就是说除了上面的name属性可以使用,其他都不能使用
@classmethod
def get_name(cls, project):
return 'this classmethod score is {}, project is {}'.format(cls.name, project)
print(Person.get_name('python'))
下面这个是静态方法
# slef是当前实例本身
class Person:
name = '杰克'
# score = 99
# __init__初始化一些属性
# 对于公共的参数可以直接写在__init__
def __init__(slef, address):
slef.score = 100
slef.address = address
# 静态方法的特点是调用属性使用类名来进行调用。不能使用cls与self,相反。classmethod会访问到cls,实例化访问self
@staticmethod
def get_name(project):
return 'Name is {} {}'.format(Person.name, project)
print(Person.get_name('python'))
getatter反射的用法
# slef是当前实例本身
class Person:
name = '杰克'
# score = 99
# __init__初始化一些属性
# 对于公共的参数可以直接写在__init__
def __init__(self, address):
self.score = 100
self.address = address
def get_name(self,project):
return 'Name is {} ,project is {}'.format(self.name,project)
sp = Person('BeiJing')
# 反射
res = getattr(sp, 'get_name')
print(res('python'))
items()方法学习:
items()表示返回一个可迭代的元组数组。主要是用在字典上面。比如
>>> a = {'a':1,'b':2,'c':3,'d':4,'e':5,'f':6}
>>> b = sorted(a.items())
>>> b
[('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6)]
对于items的返回对象可以使用切分,比如:
b[:5]表示截取前五个元组
python django
# urls.py文件内容如下所示:
from .views import hello
urlpatterns = [
path('admin/', admin.site.urls),
# name='hello'这个可以不用写,写了的话表示template可以直接引用的
re_path(r'^hello/([a-zA-Z]+)/([0-9]+)/$', hello , name='hello')
]
# views.py文件内容如下所示:
from django.http import HttpResponse, JsonResponse
#
#
# # 这里的第一个参数必须是request
# def hello(request):
# # httpresponse返回的是字符串,而jsonresponse返回的是json格式的文本
# return HttpResponse('hello')
#
#
# # 尝试返回字典
def hello(request, *args):
a = {
'Name': args[0],
'age': args[1]
}
return JsonResponse(a
)
在django中通过命令行给数据库传送数据
数据库里面分别是这几个字段
MariaDB [dja]> desc cmdb_idc;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(32) | NO | | NULL | |
| address | varchar(64) | NO | | NULL | |
| remark | longtext | NO | | NULL | |
+---------+-------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)
python manage.py shell
# 第一种方法
>>> from cmdb.models import Idc
>>> Idc.objects.create(name='昌平机房', address='北京市昌平区', remark='first computer')
<Idc: 昌平机房>
>>> Idc.objects.create(name='云泰机房',address= '内 古鄂尔多斯市', remark='second computer')
<Idc: 云泰机房>
>>> Idc.objects.create(name='天蝎机房', address='江西省抚州市',remark='third computer')
<Idc: 天蝎机房>
# 第二种方法
>>> data = {'name':'厦门一号机房','address':'福建省厦门市','remark':'fourth computer'}
>>> Idc.objects.create(**data)
<Idc: 厦门一号机房>
既然加入了数据那么就可以查询到数据
# 根据name来进行查找
>>> Idc.objects.get(name='昌平机房')
<Idc: 昌平机房>
>>> idc=Idc.objects.get(name='昌平机房')
>>> idc.name
'昌平机房'
>>> idc.id
1
>>> idc.address
'北京市昌平区'
>>> idc.remark
'first computer'
# 根据id号进行查找
>>> idc=Idc.objects.get(id=1)
>>> idc
<Idc: 昌平机房>
>>> idc.name
'昌平机房'
>>> idc.address
'北京市昌平区'
queryset与object的区别,object是通过modelname.objects.get方法得到,是一个数据对象,而queryset是通过modelname.objects.filter/all/exclude等方法得到,是一个查询集合。包含0个或多个的查询集合。
并且object只能获取一个数据,如果返回多个,就报错了。
>>> idc = Idc.objects.filter(id=1)
>>> idc
<QuerySet [<Idc: 昌平机房>]> # 看的出来是一个集合
>>> idc.get()
<Idc: 昌平机房>
>>> idc = Idc.objects.all()
>>> idc
<QuerySet [<Idc: 昌平机房>, <Idc: 云泰机房>, <Idc: 天蝎机房>, <Idc: 厦门一号机房>]>
>>> for i in idc:
... print(i)
...
昌平机房
云泰机房
天蝎机房
厦门一号机房
先查询,如果有则查询出来,如果没有则创建,也就是说对象不存在则创建,返回元祖(对象, 布尔值)
>>> Idc.objects.get_or_create(name='haha')
(<Idc: haha>, True) # 这个True表示数据库没有从而执行了创建操作。
>>> res = Idc.objects.filter(name='昌平机房').first()
>>> res
<Idc: 昌平机房>
删除操作
# 删除一个
>>> Idc.objects.filter(id=1).delete()
(1, {'cmdb.Idc': 1})
>>> idc = Idc.objects.all()
>>> idc
<QuerySet [<Idc: 云泰机房>, <Idc: 天蝎机房>, <Idc: 厦门一号机房>]>
# 删除全部
>>> Idc.objects.all().delete()
(3, {'cmdb.Idc': 3})
>>> idc = Idc.objects.all()
>>> idc
<QuerySet []> # 全部都删除了
# 对查询到的数据然后删除掉
Idc.objects.filter(name='aaa').delete() # 所有name是aaa的数据删除掉
查询
# 对查询到的数据进行更新address地址
>>> Idc.objects.create(name='北京市') # 只创建了name,但address为空
<Idc: 北京市>
>>> Idc.objects.create(name='天津市')
<Idc: 天津市>
>>> Idc.objects.create(name='北京市')
<Idc: 北京市>
>>> Idc.objects.all()
<QuerySet [<Idc: 北京市>, <Idc: 天津市>, <Idc: 北京市>]>
>>> Idc.objects.filter(name='北京市').all()
<QuerySet [<Idc: 北京市>, <Idc: 北京市>]>
>>> Idc.objects.filter(name='北京市').update(address='都在北京市里面')
2
>>> idc = Idc.objects.filter(name='北京市').all()
>>> for i in idc:
... print(i.address)
...
都在北京市里面
都在北京市里面
现在查看一下数据
MariaDB [dja]> select * from cmdb_idc;
+----+-----------+-----------------------+--------+
| id | name | address | remark |
+----+-----------+-----------------------+--------+
| 11 | 北京市 | 都在北京市里面 | |
| 12 | 天津市 | | |
| 13 | 北京市 | 都在北京市里面 | |
+----+-----------+-----------------------+--------+
3 rows in set (0.00 sec)
更新所有字段的数据
Idc.objects.all().update(address='xxxxx')
异常捕获
>>> try:
... idc = Idc.objects.get(id=100)
... except Idc.DoesNotExist:
... idc = 'Not'
...
>>> idc
'Not'
排序
Idc.objects.order_by('name') # 从小到大排序
Idc.objects.order_by('-name') # 从大到小排序
查最后一个元素
idcs = Idc.objects.all()
idcs[len(idcs)-1]
# 查询总数
idcs.count()
上面我们列出的filter表示等于= ,而不等于!=则使用exclude,返回的依然是queryset查询集合
>>> idc = Idc.objects.exclude(id=11) # 这是id不等于11的查询结果
>>> idc
<QuerySet [<Idc: 天津市>, <Idc: 北京市>]>
django之聚合查询
__exact与__iexact区别
__exact相当于=
__iexact相当于like
事实上两者在django里面使用时结果都一样,有些资料写exact是精确匹配,iexact是精确匹配但忽略大小写,事实上两者都忽略了大小写,结果是一样的。
在mysql里面:select * from table where name binary = 'aaa';才表示注意大小写,要加上binary才可以,而exact与iexact并没有资料说对应binary,所以两个结果一样。
__contains与__icontains区别
icontains不区分大小写的包含匹配
contains区分大小写的包含匹配
创建带有默认值sql语句
class Idc(models.Model):
'''
机房表
'''
name = models.CharField(max_length=32, null=True, black=True, default='用户没有填写')
address = models.CharField(max_length=64)
remark = models.TextField()
# 下面可写可不写,主要是定义名字的
def __str__(self):
return self.name
批量创建
from cmdb.models import Idc
idc1 = Idc(name='aaa')
idc2 = Idc(name='bbb')
idc3 = Idc(name='ccc')
Idc.objects.bulk_create([idc1,idc2,idc3])
[<Idc: aaa>, <Idc: bbb>, <Idc: ccc>]
定义为抽象类
from django.db import models
class BasicModel(models.Model):
name = models.CharField(max_length=32, null=True, default='render')
remark = models.CharField(max_length=32)
# 定义当前这个类是抽象类
class Meta:
abstract = True
class Idc(BasicModel):
'''
机房表
'''
address = models.CharField(max_length=64)
# 下面可写可不写,主要是定义名字的
# def __str__(self):
# return self.name
class Rack(BasicModel):
number = models.CharField(max_length=32)
# 然后查看表
MariaDB [dja]> show tables;
+----------------------------+
| Tables_in_dja |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| cmdb_idc |
| cmdb_rack |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
12 rows in set (0.01 sec)
发现并没有BasicModel表,是因为这个表定义为了抽象表,此时不会在数据库中进行创建
使用name_handler方法
class BasicModel(models.Model):
name = models.CharField(max_length=32, null=True, default='render')
remark = models.CharField(max_length=32)
# 定义当前这个类是抽象类
class Meta:
abstract = True
class Idc(BasicModel):
'''
机房表
'''
address = models.CharField(max_length=64)
def name_handle(self):
return 'renderg-------' + self.name
# 然后测试一下
>>from cmdb.models import Idc
>>idc = Idc.objects.get(id=1)
>>idc.name_handle()
'renderg-------厦门一号机房'
>>idc.name
'厦门一号机房'
所以从这里可以看出来,使用name_handler的话可以对结果进行指定的输出,即可以加工数据。而单纯的name依然表示输出最原始的数据
model_to_dict的用法
>>> data = [model_to_dict(i,exclude=['id']) for i in Idc.objects.all()]
>>> data
[{'name': '厦门一号机房', 'remark': '合作一', 'address': '福建省厦门市'}]
>>> Idc.objects.create(name='抚州天蝎机房',address='江西省抚州市',remark='二次合作')
<Idc: Idc object (2)>
>>> data
[{'name': '厦门一号机房', 'remark': '合作一', 'address': '福建省厦门市'}]
>>> data = [model_to_dict(i,exclude=['id']) for i in Idc.objects.all()]
>>> data
[{'name': '厦门一号机房', 'remark': '合作一', 'address': '福建省厦门市'}, {'name': '抚州天蝎机房', 'remark': '二次合作', 'address': '江西省抚州市'}]
>>> data = [model_to_dict(i,exclude=['id','remark']) for i in Idc.objects.all()]
>>> data
[{'name': '厦门一号机房', 'address': '福建省厦门市'}, {'name': '抚州天蝎机房', 'address': '江西省抚州市'}]
看的出来需要排除哪个字段 ,就在exclude里面写哪个字段
排除错误经验之一:
今天遇到比较难缠的问题,写了个不合适的代码,导致python manage.py migrate出现错误,但是找不出来具体原因,只能归结到是代码的问题了。但是在解决的过程中比较诡异,我即便把代码注释,这个类都注释了,也依然报这个错误,看的出来是缓存的问题在搞鬼,所以就把项目cmdb下面的migrations目录下文件都给删除了,重新执行python manage.py makemigrations,但是很奇怪,执行这个语句一直报'No changes detected',我明明改变了代码,肯定要打印出来我改变的文件的提示才对,因为我断定这个命令不太对,百度了一下最后这样子执行了python manage.py makemigrations cmdb
,也就是针对cmdb项目生成migrations文件信息,这样子就成功了,最后再执行python manage.py migrate就OK了。
插播两条代码
Idc.objects.create(name='厦门一号机房',address='福建省厦门市',remark='renderg一起合作第一个机房')
<Idc: Idc object (1)>
data = {'name':'厦门二号机房','address':'福建省厦门市','remark':'renderg一起合作第二个机房'}
数据库一对多关系
先把实现的models类的代码贴出来,才能讲下面的python
from django.db import models
# Create your models here.
from django.db import models
class BasicModel(models.Model):
name = models.CharField(max_length=32, null=True, default='render')
remark = models.CharField(max_length=32)
# 定义当前这个类是抽象类
class Meta:
abstract = True
class Idc(BasicModel):
'''
机房表
'''
address = models.CharField(max_length=64)
def name_handle(self):
return 'renderg-------' + self.name
# 下面可写可不写,主要是定义名字的
# def __str__(self):
# return self.nameidc
class Rack(BasicModel):
idc = models.ForeignKey(Idc, on_delete=models.SET_NULL, null=True, default='')
number = models.CharField(max_length=32)
上面的代码是提示,实现效果如下所示
# 两种给外键idc传值的方法,如下所示:
from cmdb.models import Rack
Rack.objects.create(name='A机柜',idc_id=1)
<Rack: Rack object (1)>
idc = Idc.objects.get(id=1)
Rack.objects.create(name='B机柜',idc = idc) # 注意第二个idc是Idc类的实例化对象,可以直接赋值给Rack类中的idc(或者说是数据库的字段)
<Rack: Rack object (2)>
主键和外键关联表查询方式,实现的需求是根据机房查询出来这个机房的所有机柜,两种方法
# 第一种是先查询机柜的外键值(即机房),然后根据这个外键值过滤出来这个符合条件的机柜。这种方法是站在机柜的角度来查询。这种称为反向查,通过子表查外键表
rack = Rack.objects.filter(idc_id = 1)
for i in rack:
print(i.name)
A机柜
C机柜
# 第二种方法是站在机房的角度,过滤出来机房,然后查询这个机房的所有机柜。这种称为通过外键表查子表
idc = Idc.objects.get(id=1)
idc.rack_set.all()
<QuerySet [<Rack: Rack object (1)>, <Rack: Rack object (4)>]>
rack = idc.rack_set.all() # 这里的rack_set中的rack就是机柜类的小写而已,所有这个名字是会变化的,后面的_set是固定的。即 表名_set
for i in rack:
print(i.name)
A机柜
C机柜
通过上面这个例子,我们看到可以通过 表名_set
的方式来引用,这种名称或许不太好看,我们可以这样子来做
class Rack(BasicModel):
idc = models.ForeignKey(Idc, on_delete=models.SET_NULL, null=True, default='',related_name='IDC_RACK') # 这里定义了related_name
number = models.CharField(max_length=32)
# 下面我们看一下
from cmdb.models import Idc,Rack
idc = Idc.objects.get(id=1)
idc.IDC_RACK.all()
<QuerySet [<Rack: Rack object (1)>, <Rack: Rack object (4)>]>
for i in idc.IDC_RACK.all(): # 所以这里可以通过上面的定义的related_name来引用,这就是这个关键字的作用
print(i.name)
A机柜
C机柜
接下来我们学习一下多对多的关系
同样的,多对多的关系我们得知道是谁和谁之间多对多,比如这里的,是服务器和用户之间,一个用户可以有多个机器,一个机器可以被多个用户同时使用。
先把代码实现写在这里
from django.contrib.auth.models import User
class Server(BasicModel):
CPU = models.CharField(max_length=32)
Memory = models.CharField(max_length=32)
user = models.ManyToManyField(User,null=True, default='')
接下来我们看实现过程
from django.contrib.auth.models import User
User.objects.get(id=3) # 这是u2用户(已提前在后台创建完)
<User: u2>
User.objects.get(id=2) # 这是u1用户(已提前在后台创建完)
<User: u1>
User.objects.get(username='u1')
<User: u1>
u1 = User.objects.get(username='u1')
s1 = Server.objects.get(id=1)
s1.user.add(u1) # 这个是说把服务器1给用户u1使用
s1.user.all() # 这里可以看到服务器被哪个用户使用
<QuerySet [<User: u1>]>
u1.server_set.all() # 这个可以看到用户u1使用了哪些机器
<QuerySet [<Server: Server object (1)>, <Server: Server object (2)>]>
u = u1.server_set.all() # 循环打印出来
for i in u:
print(i.name)
dell01
dell02
# 我们上面实现了根据服务器指定哪个用户使用,我们也可以换个思想,即用户指定使用哪个机器的方式
Server.objects.create(name='dell03',id=3)
<Server: Server object (3)>
s3 = Server.objects.get(id=3)
s3
<Server: Server object (3)>
u1.server_set.add(s3) # 指定u1用户使用s3这个刚刚新创建的机器
for i in User.objects.get(id=2).server_set.all(): # 这里写了这么长也仅仅表示查询出来这个用户u2,然后打印出他使用的所有的机器。里面的server_set是固定写法,即表名_set
print(i.name)
dell01
dell02
dell03
用户权限
接下来我们学习用户权限
from django.contrib.auth.models import Permission,User,Group
u = User.objects.get(username='u1')
u
<User: u1>
u.user_permissions.all() # 初次使用,发现是没有任何权限的
<QuerySet []>
perm = Permission.objects.get(codename='add_idc') # 我们获取一个add_idc的权限
u.user_permissions.add(perm) # 然后给u1这个用户
# 接下来是获取权限,有以下几种方式
# 第一个
u.user_permissions.all()
<QuerySet [<Permission: cmdb | idc | Can add idc>]> # 可以看到现在u1用户有权限了
# 第二个
u.get_all_permissions()
{'cmdb.add_idc'}
# 第三个,根据true或false的方式来解决
u.has_perm('cmdb.add_idc')
True
u.has_perm('cmdb.delete_idc')
False
# 检查一个用户是否有这个权限也可以这样子操作
'cmdb.delete_idc' in u.get_all_permissions()
False
'cmdb.add_idc' in u.get_all_permissions()
True
perm
<Permission: cmdb | idc | Can add idc>
# 下面这种方式得先获取perm,所以较为麻烦,一般也不用这种方法,而且这种方法获取的只是用户本身的权限,一般我们说的用户的权限是用户自己的权限+用户所在组的权限的和,所以下面这个使用上有一定的误差
perm in u.user_permissions.all()
True
给组添加权限,当用户添加到这个组中时,自动集成这个组的权限
# 咱们先来给组添加权限
from django.contrib.auth.models import Permission,User,Group
perm = Permission.objects.get(codename='add_idc')
perm
<Permission: cmdb | idc | Can add idc>
Group.objects.all()
<QuerySet []>
Group.objects.all() # 刚刚在web上添加了一个用户g1,因此现在才查看到了。
<QuerySet [<Group: g1>]>
g1 = Group.objects.get(name='g1')
g1
<Group: g1>
g1.permissions.add(perm) # 给这个组添加权限
g1.permissions.all()
<QuerySet [<Permission: cmdb | idc | Can add idc>]>
# 现在咱们把用户添加到组中
u2 = User.objects.get(username='u2') # 找到u2用户
u2.get_all_permissions() # u2是新用户没有任何权限
set()
g1.user_set.add(u2) # 把u2用户添加到g1组里面
u2.groups.all() # 可以看到u2用户所在的组
<QuerySet [<Group: g1>]>
u2.get_all_permissions() # 现在是看不到u2的权限的,还没生效,重新获取一下
set()
u2 = User.objects.get(username='u2')
u2
<User: u2>
u2.get_all_permissions() # 可以看到u2用户现在已经集成了g1组的add_idc权限了
{'cmdb.add_idc'}
# 再来添加几个权限
p1 = Permission.objects.get(codename='delete_idc')
p2 = Permission.objects.get(codename='add_server')
u2.get_all_permissions()
{'cmdb.add_idc'}
g1.permissions.add(p1,p2) # 把新的p1和p2权限添加到这个组上面
g1.permissions.all() # 顺便查看查看g1组现在的权限
<QuerySet [<Permission: cmdb | idc | Can add idc>, <Permission: cmdb | idc | Can delete idc>, <Permission: cmdb | server | Can add server>]>
u2 = User.objects.get(username='u2')
u2.get_all_permissions() # 现在来看看g1组里面u2这个用户的权限
{'cmdb.add_idc', 'cmdb.delete_idc', 'cmdb.add_server'}
html
现在学习一下html
<body>
<p style="color: red;margin-left: 100px">新年好啊</p>
</body>
如下效果所示:
还可以用下面这个方法,都是一样的
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
p {color: red;margin-left: 100px} # 这里的p表示body里面的<p>标签都会生效
</style>
</head>
<body>
<p>新年好啊</p>
</body>
使用容器div,容器主要是一个块,当对容器声明一些属性的时候,整个容器内容都会生效,比如这里,对这个div标签设置距离左侧100像素,距离顶部200像素
<body>
<div style="margin-left: 100px;margin-top: 200px">
<p>新年好啊</p>
<ul>
<li>coffee</li>
<li>Milk</li>
</ul>
</div>
</body>
效果如下:
添加超链接
<body>
<div style="margin-left: 100px;margin-top: 200px">
<p>新年好啊</p>
<ul>
<li>coffee</li>
<li>Milk</li>
</ul>
<a href="http://www.baidu.com/" target="_blank">点击百度搜索</a>
</div>
</body>
效果如下:
上面的加上 target="_blank"
意味着我们点击超链接之后会启动一个新的窗口并打开此页面
使用bootstrap实现,把超链接加在按钮上面
<a href="http://www.baidu.com/" target="_blank">
<button type="submit" class="btn btn-success">点击百度搜索</button>
</a>
效果如下所示:
可以实现下拉菜单的操作:
<!-- Single button -->
<div class="btn-group">
<button type="button" class="btn btn-primary">动作</button>
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a href="www.baidu.com">百度</a></li>
<li><a href="www.qq.com">QQ</a></li>
<li><a href="www.weixin.com">微信</a></li>
<li role="separator" class="divider"></li>
<li><a href="www.sohu.com">搜狐</a></li>
</ul>
</div>
使用div的class。并定义class类型
在写视图的时候,如果类集成的是ListView,那么有点需要注意的是,我们传递的上下文变量默认值是object_list作为上下文变量,当然可以自定义,使用context_object_name进行重命名,ListView里面有get_queryset方法,主要就是用来返回数据列表的
如果是列表页的话,首选ListView,其他的选择TemplateView。
输入框鼠标点击弹窗
<div>
<input id='input1' style='width: 100px'>
<input id='input2' style='width: 100px'>
</div>
<button id="btn1" type="button" class="btn btn-success" >百度</button>
<script type="text/javascript">
$('#btn1').click(function(){
n1=$('#input1').val()
n2=$('#input2').val()
//alert(parseInt(n1)+parseInt(n2));
alert(n1+n2);
})
</script>