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>

posted @ 2021-02-03 09:30  峰哥ge  阅读(152)  评论(0编辑  收藏  举报