django基本操作与路由层

Django的基本操作

一、数据的增删改查

1.1 数据的查看

1.1.1 get()

​ 当查询条件不存在的时候 会直接报错 如果存在会直接给你返回 数据对象本身 ,不推荐使用。

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # select * from ? where ?
        res = models.Userinfo.objects.get(username=username)
        print(res)
        print(res.username)

1.1.2 filter()

​ filter可以当多个查询条件 并且是and关系,多个条件使用逗号隔开,当查询条件不存在的时候 ,不会报错而是返回一个空, 当条件存在的情况下 无论数据有几条返回的都是列表套对象的数据格式。

# select * from ? where ?
res = models.Userinfo.objects.filter(username=username)

​ 可以将filter查询出来的结果当做列表去对待 支持正数的索引取值和切片 不支持负数,但是不推荐使用索引取值。

user_obj = res[0]
user_obj = res[0:3]

​ 推荐取值方法:

# 取出第一个元素
user_obj = res.first()
# 取出最后一个元素
user_obj = res.last()

1.2 数据的增加

​ create()方法括号内写关键字的形式创建数据,该方法会有一个返回值,返回值就是当前对象本身。

def reg(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        pwd = request.POST.get('pwd')
        # insert into userinfo(username,password) values ('username','pwd)
        user_obj = models.Userinfo.objects.create(username=username,password=pwd)
	return render(request, 'register.html')

​ 使用类实例化产生对象点save()方法对数据进行处理:

user_obj = User(username = 'daxiong')
user_obj.save()   # 保存到数据库

1.3 数据的修改

​ 选取用户想要编辑的数据:

def edit_user(request):
    edit_id = request.GET.get('edit_id')
    print(user_queryset.query)  
    # 只有queryset对象才能够点query查询内部所对应的sql语句

​ 获取用户新修改的所有信息:

	if request.method =='POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # POST中也是可以获取GET请求携带的参数

​ 修改方法一:

models.Userinfo.object.filter(pk=edit_id).update(username=username,password=password) 

​ 修改方法二:获取当前数据对象 然后利用对象点属性的方式 先修改数据 然后调用对象方法保存

edit_obj = models.Userinfo.object.filter(pk=edit_id).first()
edit_obj.username = username
edit_obj.password = password
edit_obj.save()

​ 不推荐使用第二种,因为save()会将数据全部重新修改,是处理效率降低。

return redirect('/userlist')
    #根据主键值去数据库中查询出当前对象 展示给用户看
edit_obj = models.Userinfo.objects.filter(pk=edit_id).first()  # pk能够自动帮你查询出当前表的主键字段名
    # 将查询出来的数据对象传递给前端页面 展示给用户看
return render(request,'edit_user.html',locals())

1.4 数据的删除

​ 获取想要删除的数据ID,直接删除:

def delete_user(request):
    delete_id = request.GET.get('delete_id')
    models.Userinfo.objects.filter(pk=delete_id).delete()
	retuen redirect('/userlist')

二、表设计

​ 在models中进行表设计以图书-作者-出版社的关系为例:

class Book(models.Model):
    title = models.CharField(max_lenth=32)
    # 总长度8位,小数两位
    price = models.DecimalField(max_difits=8,decimal_places=2)
    
class Publish(models.Model):
	name = models.CharField(max_length=32)
    addr = models.CharField(max_length=255)
    
class Author(models.Model):
    name = models.CharField(max_length=32)
    phone = models.BigIntegerField()

​ 书和出版社是一对多关系,外键放在多的那一侧:

publish = models.ForeignKey(to='Publish')
#to指定跟谁是外键关联的  默认关联的是表的主键字段
#ForeignKey字段  django orm在创建表的时候 会自动给该字段添加_id后缀,如果名字带id后缀,还会继续添加

​ 书和作者是多对多关系,外键可以放在任意一方,推荐放在使用平率高的一方:

author = models.ManyToManyField(to='Author')
#authors字段仅仅是一个虚拟字段 不会再表中展示出来  仅仅是用来告诉django orm 书籍表和作者表示多对多的关系自动创建第三张表 

​ 作者作者详情是一对一关系, 一对一字段建在哪张表都可以 但是推荐建在 查询频率比较高的那张表:

author_detail = models.OneToOneField(to='AuthorDetail')
#OneToOneField字段  django orm在创建表的时候 会自动给该字段添加_id后缀

三、django请求生命周期

img

四、路由层(urls.py)

4.1 有名分组与无名分组

​ url内第一个参数的内容要求以正则规范进行拼写:

	url(r'^admin/', admin.site.urls),
    url(r'^$', views.home),  # 首页
    url(r'^index/', views.index),
    url(r'^test/$', views.test),
    url(r'testadd/', views.testadd),
    url(r'',views.errors)  # 404页面 一定放在最后一排

​ 无名分组:会将括号内匹配到的内容当做位置参数,传递给后面的视图函数test(request,args):

url(r'^test/(d+)/',views.test)

​ 有名分组:会将括号内匹配到的内容当做关键字参数,传递给后面的视图函数test(request,month=123)

url(r'^test/(?P<month>d+)/', views.test)

​ 注意:有名分组无名分组不能一起使用,单独使用时可以使用多个:

url(r'^test/(d+)/(d+)/)',view.test,
url(r'^test/(?P<xxx>d+)/(?P<yyy>)d+/'),view.text

url(r'^test_addsajdsjkahdkjasjkdh/(d+)/', views.testadd,name='xxx'),
url(r'^test_addsajdsjkahdkjasjkdh/(?P<year>d+)/', views.testadd,name='xxx'),

def test(request,xxx,month):

    print(xxx)
    print(month)
    return HttpResponse('test')

4.2 反向解析

​ 在软件开发初期,url地址的路径设计可能并不完美,后期需要进行调整,如果项目中很多地方使用了该路径,一旦该路径发生变化,就意味着所有使用该路径的地方都需要进行修改,这是一个非常繁琐的操作。
​ 解决方案就是在编写一条url,可以通过参数name为url地址的路径部分起一个别名,项目中就可以通过别名来获取这个路径。以后无论路径如何变化别名与路径始终保持一致。
​ 上述方案中通过别名获取路径的过程称为反向解析。

 url(r'^test_add/', views.testadd,name='xxx')

​ 前端:

{% url 'xxx' %}

​ 后端:

from django.shortcuts import render,HttpResponse,redirect,reverse
url = reverse('xxx')

​ 无名分组反向解析:

  url(r'^test_addsajdsjkahdkjasjkdh/(d+)/', views.testadd,name='xxx'),
# 前端
 <a href="{% url 'xxx' 1 %}">222</a>
# 后端
url = reverse('xxx',args=(1,))

​ 有名分组反向解析:

url(r'^test_addsajdsjkahdkjasjkdh/(?P<year>d+)/', views.testadd,name='xxx'),
# 前端
 <a href="{% url 'xxx' 1 %}">222</a>
# 后端
url = reverse('xxx',args=(1,))

# 前端完整版
<a href="{% url 'xxx' year=1 %}">222</a>
# 后端完整版
url = reverse('xxx',kwargs={'year':123})

​ 注意:反向解析的别名 一定不要重复

4.3 路由分发

​ 随着项目功能的增加,app会越来越多,路由也越来越多,每个app都会有属于自己的路由,如果再将所有的路由都放到一张路由表中,会导致结构不清晰,不便于管理,所以应该将app自己的路由交由自己管理,然后在总路由表中做分发。

​ django里面的app可以有自己的static文件,templates文件夹,urls.py。项目名下面的urls.py不再做路由与视图函数对应关系而是做一个中转站 只负责将请求分发到不同的app中,然后在app的urls.py完成路由与视图函数的对应关系:

from django.conf.urls import url,include

url(r'^app01/',include(app01_urls)),
url(r'^app02/',include(app02_urls))

4.4 名称空间

​ 一个项目下创建了多个app,并且每个app下都针对匹配的路径起了别名,如果别名存在重复,那么在反向解析时则会出现覆盖问题。

​ 解决这个问题的方法之一就是避免使用相同的别名,如果就想使用相同的别名,那就需要用到django中名称空间的概念,将别名放到不同的名称空间中,这样即便是出现重复,彼此也不会冲突。

​ 总路由:

url(r'^app01/',include('app01.urls',namespace='app01'))
       url(r'^app02/',include('app02.urls',namespace='app02'))
        
print(reverse('app01:index'))
print(reverse('app02:index'))

​ 通常情况下 起别名的时候 前面可以加上你的应用名。

4.5 伪静态

​ 将动态网页假装成是静态的,搜索在收录网站的时候 会优先收录看上去像是静态文件的资源,将动态网页假装成是静态的目的就是为了提高搜索引擎的SEO查询优先级,提高搜索量。

4.6虚拟环境

​ 通常针对不同的项目只会安装该项目所用的模块 用不到的一概不装,使用虚拟环境可以使不同的项目有专门的解释器环境与之对应,提高效率。

​ 每创建一个虚拟环境 就类似于重新下载了一个纯净的python解释器,因此虚拟环境不要创建太多个 。

4.7 django版本的区别

​ django1.x用的是url。

​ django2.x用的是path,并且path第一个参数不支持正则表达式,写什么就匹配什么。但是有个re_path,与url是同样的用法。

​ django2.x中path内的<>内可以使用转换器,django默认支持一下5种转换器:

str  #匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int  #匹配正整数,包含0。
slug  #匹配字母、数字以及横杠、下划线组成的字符串。
uuid  #匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path  #匹配任何非空字符串,包含了路径分隔符(/)(不能用?)

原文地址:https://www.cnblogs.com/tangceng/p/11724232.html