Django目录介绍、路由系统、 ORM表的创建、XSS攻击、分页、 CBV & FBV

Django目录介绍、路由系统、 ORM表的创建

Django目录介绍
        django-admin startproject mysite  在终端创建目录
        cd mysite
        python manage.py startapp app01    创建一个app 
        
        project
            - app01
                -migrations  和数据库相关,和modal相关
                - admin   Django自带后台管理相关配置
                - modal   写类,根据类创建数据库表
                - test    单元测试
                - views   业务处理,业务可以分类
            - app02
            - app03

    1. 路由系统(位置参数和形式参数不要不要混用,*args,**kwargs可以接收参数)
        url -> 函数
        
        a. /login/ -> def login        SEO权重不高
        
        b. /add-user/(\d+)/  ->  def add_user(request,a1)
           /add-user/(\d+)/(\d+)/ ->  def add_user(request,a1,a2)    位置参数
        
        c. /add-user/(?P<a1>\d+)/  ->  def add_user(request,a1)        形式参数
        
        url(r'^index/', views.index),   访问时必须index/这种形式
        url(r'^index$', views.index),   访问时必须index这种形式
        url(r'^index', views.index),     访问时index开头的任意字符串都可以访问
        url(r'^index/(\d+).html', views.index),   访问时必须index/(\d+).html开头的这种形式
        url(r'^', views.index)            没有匹配成功,设置默认html
        PS: 
            终止符:
                ^edit$
            伪静态    提高SEO权重
                url(r'^edit/(\w+).html$', views.edit),
        d. 路由分发
            urls.py中
            导入from django.conf.urls import include
                url(r'^app01/', include('app01.urls')),
                
                先在总路由匹配app路径,然后去该app下urls.py中去匹配路径
                
            
            app01.urls.py
                url(r'^index.html$', views.index),
                
        e. 路由系统之别名反向生成url            
            
            根据名称可以反向生成URL
            1. url(r'^index/', views.index,name="n1)
            在Python代码中,在viws.py中
            def index(request):
                from django.urls import reverse
                v = reverse('n1')
                print(v)    #生成url路径/index/
                
                
             url(r'^index/(\d+)/', views.index,name="n1)
            在Python代码中,在viws.py中
            def index(request,a1):
                from django.urls import reverse
                v = reverse('n1',args={451})
                print(v)    #生成url路径/index/451/
                        
             url(r'^index/(?P<a1>\d+)/', views.index,name="n1)
            在Python代码中,在viws.py中
            def index(request,a1):
                from django.urls import reverse
                v = reverse('n1',kwargs={'a1':1111})
                print(v)    #生成url路径/index/1111/
            
            2. 在路由文件中
                url(r'^login/', views.login,name='m1')
                在html文件中
                {% url "m1" %} 提交就可以找到/login/路径
                
                在路由文件中
                url(r'^login/(\W)/', views.login,name='m1')
                url(r'^login/(\W).html$', views.login,name='m1')
                在html文件中
                {% for i in user_list %}
                    <li>{{ i }}|<a href="{% url "m1" i %}">编辑</a></li>
                {% endfor %}
                提交就可以找到/login/i路径
                提交就可以找到/login/i.html路径
                
                
            
    3. ORM操作
        ORM利用pymysql第三方工具连接数据库
        默认:使用SQLlite 数据库
        Http请求:
            url -> 视图(模板+数据)
        步骤:
            1. 创建数据库:在数据库创建70db
            2. 在settings中设置
                # DATABASES = {
                #     'default': {
                #         'ENGINE': 'django.db.backends.sqlite3',
                #         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
                #     }
                # }

                DATABASES = {
                    'default': {
                        'ENGINE': 'django.db.backends.mysql',
                        'NAME':'70db',
                        'USER': 'root',
                        'PASSWORD': '',
                        'HOST': 'localhost',
                        'PORT': 3306,
                        }
                }
        3. 在项目__init__.py中更换默认连接数据库的方式,MySQLDB(修改django默认连接mySQL方式)
            import pymysql
            pymysql.install_as_MySQLdb()
    
    
        4.在app下的models.py下:创建表
        from django.db import models
        
        class user_group(models.Model):
            title = models.CharField(max_length=32)

        class user_info(models.Model):
            id = models.BigAutoField(primary_key=True)   #这一列不写也会自动生成
            username=models.CharField(max_length=32)
            password=models.CharField(max_length=64)
            # age = models.IntegerField(null=True)  #设置可以为空,创建表后插入这一列时可以这么设置
            age = models.IntegerField(default=1)
            #默认生成ug_id,设置可以为空,创建表后插入这一列时可以这么设置
            ug = models.ForeignKey("user_group",null=True)
            

        
        5.在配置中注册app
        INSTALLED_APPS = [
            'django.contrib.admin',
            'django.contrib.auth',
            'django.contrib.contenttypes',
            'django.contrib.sessions',
            'django.contrib.messages', 
            'django.contrib.staticfiles',
            'app01'
        ]
        
        6.创建数据表
            命令:
            python manage.py makemigrations
            python manage.py migrate
   
        

 

 ORM表的操作

ORM操作表:
            创建表
            修改表
            删除表
        操作数据行:
            增删改查
            基于ORM实现组表操作
            #新增
             models.user_group.objects.create(title="销售部")
             models.user_info.objects.create(user='root',password='pwd',age=18,ug_id=1)
             查找
             group_list = models.user_group.objects.all()
                models.user_group.objects.all().count()  统计个数              
        group_list
= models.user_group.objects.filter(id=1) group_list = models.user_group.objects.filter(id__gt=1) #大于 group_list = models.user_group.objects.filter(id__lt=1) #小于 print(group_list) #group_list是QuerySet类型,可以看成列表 group_list QuerySet类型(列表) QuerySet类型[obj,obj,obj] for row in group_list: print(row.id,row.title) models.user_info.objects.all() 删除 models.user_group.objects.filter(id=2).delete() 更新 models.user_group.objects.filter(id=2).update(title='公关部') 基于ORM实现员工表操作 1.增加 models.UserInfo.objects.create(user='root',password='123',age=10,ug_id=1) obj = models.UserGroup.objects.filter(id=1).first() #直接取一个值
            models.UserInfo.objects.create(user='root',password='123',age=10,ug=obj) 2. 删除: models.UserInfo.objects.filter(id=2).delete() 3. 修改: models.UserInfo.objects.filter(id=2).update(title='公关部') 4. 查询: group_list = models.UserInfo.objects.all() group_list获取的是QuerySet,内部元素是UserInfo对象,每一个对象代指一行数据, 对象中如果包含ForeignKey,则代指与其关联表的一行数据 for row in group_list: print(row.user) print(row.age) print(row.ug_id) # 用户信息关联的部门ID print(row.ug.title) # 用户信息关联的部门名称

获取QuerySet(查询集)

# 获取QuerySet(查询集)
            1.正向操作、反向操作(连表查询)
                 QuerySet[obj,obj,obj]
                 result = models.UserInfo.objects.all()
                 for obj in result:
                     print(obj.name,obj.age,obj.ut_id,obj.ut.title)

          正向操作
UserInfo,ut是FK字段
- PS: 一个用户只有一个用户类型 obj = models.UserInfo.objects.all().first() print(obj.name,obj.age,obj.ut.title)           反向操作
UserType, 表名小写_set.all()
- PS: 一个用户类型下可以有很多用户 obj = models.UserType.objects.all().first() print('用户类型',obj.id,obj.title) for row in obj.userinfo_set.all(): print(row.name,row.age) result = models.UserType.objects.all() for item in result: print(item.title,item.userinfo_set.filter(name='xx'))
2.数据获取多个数据时 1.列表查询集 [obj,obj,obj,] models.UserInfo.objects.all() models.UserInfo.objects.filter(id__gt=1) result = models.UserInfo.objects.all() for item in result: print(item.name,item.ut.title)           反向跨表:
          1. 小写的表名_set
             obj = UserGroup.objects.all().first()
             result = obj.userinfo_set.all() [userinfo对象,userinfo对象,]
          
         
          
2.字典查询集 [{id:1,name:fd},{id:1,name:fd},{id:1,name:fd},] models.UserInfo.objects.all().values('id','name') models.UserInfo.objects.filter(id__gt=1).values('id','name') 无法跨表 result = models.UserInfo.objects.all().values('id','name') for item in result: print(item['id'],item['name']) 字典查询集正向跨表 __ result = models.UserInfo.objects.all().values('id','name',"ut__title") for item in result: print(item['id'],item['name'],item['ut__title'])           反向跨表:
          2. 小写的表名
             v = UserGroup.objects.values('id','title')         
             v = UserGroup.objects.values('id','title','小写的表名称')         
             v = UserGroup.objects.values('id','title','小写的表名称__age') 

          
3.元组查询集 [(1,df),(2,'df')] models.UserInfo.objects.all().values_list('id','name') models.UserInfo.objects.filter(id__gt=1).values_list('id','name') 无法跨表 result = models.UserInfo.objects.all().values_list('id','name') for item in result: print(item[0],item[1]) 元组查询集正向跨表 __ result = models.UserInfo.objects.all().values_list('id','name',"ut__title") for item in result: print(item[0],item[1],item[2])
          反向跨表:
          3. 小写的表名
            v = UserGroup.objects.values_list('id','title')         
            v = UserGroup.objects.values_list('id','title','小写的表名称')         
            v = UserGroup.objects.values_list('id','title','小写的表名称__age') 


 

 

select_related、prefetch_related连表查询

select_related()主要针一对一和多对一关系进行优化,使用SQLJOIN语句进行优化

prefetch_related()对于多对多字段和一对多字段进行优化

参考:http://blog.csdn.net/secretx/article/details/43964607

select_related: 查询主动做连表,连表查询速度慢(适用外键对应的表数据量少时使用)
q = models.UserInfo.objects.all().select_related('ut','gp')
# select * from userinfo
# select * from userinfo inner join usertype on ...
for row in q:
    print(row.name,row.ut.title)

prefetch_related: 不做连表,做多次查询(使用外键对应的表数据量大,数据频繁查询时使用)
q = models.UserInfo.objects.all().prefetch_related('ut')
# select * from userinfo;
# Django内部:ut_id = [2,4]
# select * from usertype where id in [2,4]
for row in q:
    print(row.id,row.ut.title)

 

 

related_query_name和related_name的操作:

class Boy(models.Model):
    name=models.CharField(max_length=32)
    bpwd = models.IntegerField()
class Girl(models.Model):
    nick = models.CharField(max_length=32)
    gpwd = models.IntegerField()
class Love(models.Model):
    b=models.ForeignKey('Boy')
    g=models.ForeignKey('Girl')
    #可以如上这么写,会自动关联表的自增id,也可以指定表和关联id,如下:
    #b = models.ForeignKey(to='Boy',to_field='id')
    #g = models.ForeignKey(to='Girl',to_field='id')
外键的两种写法
class UserInfo(models.Model):
    nickname = models.CharField(max_length=32)
    username = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    gender_choices = (
        (1,''),
        (2,''),
    )
    gender = models.IntegerField(choices=gender_choices)        
class U2U(models.Model):
    #g = models.ForeignKey('UserInfo',related_query_name='boys')
    #b = models.ForeignKey('UserInfo',related_query_name='girls')
    g = models.ForeignKey('UserInfo',related_name='boys')
    b = models.ForeignKey('UserInfo',related_name='girls')    
    
外键的操作:
related_query_name
obj对象男.girls_set.all()
obj对象女.boys_set.all()
related_name
obj对象男.girls.all()
obj对象女.boys.all()        
def test(request):
    #两种创建数据的方式:
    models.U2U.objects.create(b_id=2,g_id=6)
    models.U2U.objects.create(b_id=1,g_id=6)            

    boy = models.UserInfo.objects.filter(gender=1,id=2).first()
    girl = models.UserInfo.objects.filter(gender=2,id=6).first()
    models.U2U.objects.create(b=boy,g=girl)
    #创建数据时可以放对象    
    
外键的操作举例:
UserInfo对象
xz = models.UserInfo.objects.filter(id=1).first()
# 和徐峥有关系的所有信息:U2U列表[U2U对象,2U对象,2U对象,]
result = xz.girls.all()
for u in result:
    # U2U对象
    print(u.g.nickname)
同一个表两个外键

 

v.query   查询原生sql语句
一对一操作的正反向:

 # obj = models.Blog.objects.filter(site=site).first()
    # print(obj.user.nickname)   
    # obj = models.UserInfo.objects.filter(username='sw').first()
    # print(obj.blog.site)        onetoone 反向操作时
OneToOne操作

多对多操作:有外键的情况查询操作

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


class Girl(models.Model):
    nick = models.CharField(max_length=32)

class Love(models.Model):
    b = models.ForeignKey('Boy')
    g = models.ForeignKey('Girl')
    class Meta:            #联合唯一索引
    unique_together = [
        ('b','g'),
    ]
1. 和方少伟有关系的姑娘
obj = models.Boy.objects.filter(name='方少伟').first()
love_list = obj.love_set.all()
for row in love_list:
    print(row.g.nick)


love_list = models.Love.objects.filter(b__name='方少伟')
for row in love_list:
    print(row.g.nick)

连表操作:
love_list = models.Love.objects.filter(b__name='方少伟').values('g__nick')
for item in love_list:
    print(item['g__nick'])

连表操作:
love_list = models.Love.objects.filter(b__name='方少伟').select_related('g')
for obj in love_list:
    print(obj.g.nick)
连表操作

 多对多操作:ManyToManyField、杂交、自定义关系表

1. ManyToManyField
    class Boy(models.Model):
        name = models.CharField(max_length=32)
        m = models.ManyToManyField('Girl')
        #django内置方式这一行会生成第三张关系表,即app01_boy_m,只能生成三列,如果有多行信息,自己写在第三张表
        #m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',))
        #杂交,如果这样写就只生成LOVE表

    class Girl(models.Model):
        nick = models.CharField(max_length=32)                
        
    #自定义关系表    
    #class Love(models.Model):
    #    b = models.ForeignKey('Boy')
    #    g = models.ForeignKey('Girl')
    #    class Meta:            #联合唯一索引
    #    unique_together = [
    #        ('b','g'),
    #    ]
        
        
        增加:
        obj = models.Boy.objects.filter(name='方少伟').first()
        print(obj.id,obj.name)
        obj.m.add(2)
        obj.m.add(2,4)
        obj.m.add(*[1,])
        
        删除:
        obj.m.remove(1)
        obj.m.remove(2,3)
        obj.m.remove(*[4,])
        
        覆盖修改:
        obj.m.set([1,])
        
        q = obj.m.all()
        # [Girl对象]
        print(q)
        obj = models.Boy.objects.filter(name='方少伟').first()
        girl_list = obj.m.all()
        
        obj = models.Boy.objects.filter(name='方少伟').first()
        girl_list = obj.m.all()
        girl_list = obj.m.filter(nick='小鱼')
        print(girl_list)
        
        删除第三张表的数据:
        obj = models.Boy.objects.filter(name='方少伟').first()
        obj.m.clear()

        反向操作:
        obj = models.Girl.objects.filter(nick='小鱼').first()
        print(obj.id,obj.nick)
        v = obj.boy_set.all()
        print(v)
        
        
2.杂交:
#m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',))
obj = models.Boy.objects.filter(name='方少伟').first()
# obj.m.add(1)        因为有ManyToManyField,所以不行,因为可能第三张表还有其他列
# obj.m.remove(1)    因为有ManyToManyField,所以不行,因为可能第三张表还有其他列
# obj.m.clear()     可以
v = obj.m.all()        可以
print(v)
                    
        
        
3. 自定义关系表
View Code

多对多操作,有无第三张表的情况:

# 自己反向关联,需要通多中间的表
        # v= models.Article.objects.filter(blog=blog,article2tag__tag=val)
        # 通过M2M字段,直接关联到另一张表,跳过中间件
        # v= models.Article.objects.filter(blog=blog,tags__nid=val)
View Code
class Article(models.Model):
    nid = models.BigAutoField(primary_key=True)
    title = models.CharField(verbose_name='文章标题',max_length=128)
    summary = models.CharField(verbose_name='文章简介',max_length=255)
    read_count = models.IntegerField(default=0)
    comment_count = models.IntegerField(default=0)
    up_count = models.IntegerField(default=0)
    down_count = models.IntegerField(default=0)
    create_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)
    blog = models.ForeignKey(verbose_name='所属博客',to='Blog',to_field='nid')
    category = models.ForeignKey(verbose_name='文章类型',to='Category',to_field='nid',null=True)

    type_choices=[
        (1,'Python'),
        (2,'Linux'),
        (3,'OpenStack'),
        (4,'GoLang'),
    ]

    article_type_id = models.IntegerField(choices=type_choices,default=None)

    tags = models.ManyToManyField(
        to = 'Tag',
        through='Article2Tag',
        through_fields=('article','tag'),
    )
class Tag(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(verbose_name='标签名称',max_length=32)
    blog = models.ForeignKey(verbose_name='所属博客',to='Blog',to_field='nid')
class Article2Tag(models.Model):
    article = models.ForeignKey(verbose_name='文章',to='Article',to_field='nid')
    tag = models.ForeignKey(verbose_name='标签',to='Tag',to_field='nid')
    class Meta:
        unique_together =[
            ('article','tag'),
        ]
model


分组: 

    """
    1. 分类
        category_list = models.Article.objects.filter(blog=blog).values('category_id','category__title',).annotate(c=Count('nid'))
    2. 标签
        tag_list = models.Article2Tag.objects.filter(tag__blog=blog).values('tag_id','tag__title').annotate(c=Count('id'))
    3. 时间
        # MySQL
        # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "date_format(create_time,'%%Y-%%m')"}).values('c').annotate(ct=Count('nid'))
        # SQLlite
        # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "strftime('%%Y-%%m',create_time)"}).values('c').annotate(ct=Count('nid'))

    """
    mysql:
    date_list = models.Article.objects.filter(blog=blog).values("date_format(create_time,'%%Y-%%m')").annotate(ct=Count('nid'))    #错误,values里面参数只能是列名
    # date_list = models.Article.objects.filter(blog=blog).extra(select={'c': "date_format(create_time,'%%Y-%%m')"}).values('c').annotate(ct=Count('nid')
时间格式的处理


类型处理:

from django.db.models import functions
    # models.Article.objects.filter(blog=blog).annotate(x=functions.Extract('create_time','YEAR_MONTH'))
    # models.Article.objects.filter(blog=blog).annotate(x=functions.ExtractYear('create_time'))
    """
    nid xx   create_time            x
     1  x     2018-09-01 11:11      201809
     2  x     2018-09-01 11:11      2018


    """
    # models.Article.objects.filter(blog=blog).annotate(x=functions.TruncMonth('create_time'))
    # models.Article.objects.filter(blog=blog).annotate(x=functions.Trunc('create_time',''))
    """
    nid xx   create_time            x
     1  x     2018-09-01 11:11      09


    """
    # from django.db.models import FloatField
    # from django.db.models import Value
    # v = models.Article.objects.annotate(c=functions.Cast('nid', FloatField()))    #类型转换
    # v = models.Article.objects.annotate(c=functions.Coalesce('title','summary'))    #找到第一个非空
    # v = models.Article.objects.annotate(c=functions.Concat('nid','title','summary'))  #拼接
    # v = models.Article.objects.annotate(c=functions.Concat('nid','title','summary',Value('666')))
    # v = models.Article.objects.annotate(c=functions.Greatest('nid','num'))   #取较大的值
    # v = models.Article.objects.annotate(c=functions.Length('title'))            #获取长度
    # v = models.Article.objects.annotate(c=functions.Substr('title',1,1))        #取自定长度的字符串,只能从第一位开始
ORM中的类型处理

 

进阶操作:

# 1.增删改查
            # 2. 一般:
                # models.UserInfo.objects.filter(id__gt=1) 大于 # models.UserInfo.objects.filter(id__lt=1) 小于 # models.UserInfo.objects.filter(id__gte=1) 大于等于 # models.UserInfo.objects.filter(id__lte=1) 小于等于 # models.UserInfo.objects.filter(id__in=[1,2,3]) # models.UserInfo.objects.filter(id__range=[1,2]) # models.UserInfo.objects.filter(name__startswith='xxxx') 以xxxx开头 # models.UserInfo.objects.filter(name__contains='xxxx') 内容包含xxxx # models.UserInfo.objects.filter(name__icontains='xxxx') 内容包含xxxx,不区分大小写 # models.UserInfo.objects.exclude(id=1) 不等于exclude models.UserInfo.filter(age__isnull=True) 数据为空也可以查询 # 3. 排序 user_list = models.UserInfo.objects.all().order_by('-id','name') 反向排序 user_list = models.UserInfo.objects.all().order_by('id','name') 正向排序 # 4. 分组 from django.db.models import Count,Sum,Max,Min 分组: v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')) print(v.query) 结果: #SELECT "app01_userinfo"."ut_id", COUNT("app01_userinfo"."id") AS "xxxx" FROM "app01_userinfo" GROUP BY "app01_userinfo"."ut_id" 分组后再筛选: v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) print(v.query) 结果: SELECT "app01_userinfo"."ut_id", COUNT("app01_userinfo"."id") AS "xxxx" FROM "app01_userinfo" GROUP BY "app01_userinfo"."ut_id" HAVING COUNT("app01_userinfo"."id") > 2 v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2) print(v.query) 结果: SELECT "app01_userinfo"."ut_id", COUNT("app01_userinfo"."id") AS "xxxx" FROM "app01_userinfo" WHERE "app01_userinfo"."id" > 2 GROUP BY "app01_userinfo"."ut_id" HAVING COUNT("app01_userinfo"."id") > 2 5. F,更新时用于获取原来的值 from django.db.models import F,Q 更新数据库一列: models.UserInfo.objects.all().update(age=F("age")+1) 6. Q,用于构造复杂查询条件 # 应用一: # models.UserInfo.objects.filter(Q(id__gt=1)) # models.UserInfo.objects.filter(Q(id=8) | Q(id=2)) # models.UserInfo.objects.filter(Q(id=8) & Q(id=2)) # 应用二: models.UserInfo.objects.filter(id=1,name='root') condition = { 'id':1, 'name': 'root' } models.UserInfo.objects.filter(**condition) 自动添加Q condition_dict = { 'k1':[1,2,3,4], 'k2':[1,], } con = Q() for k,v in condition_dict.items(): q = Q() q.connector = 'OR' for i in v: q.children.append(('id', i)) con.add(q,

转载于:https://www.cnblogs.com/domestique/p/7077279.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值