Django框架实现字典循环 路由系统中的正则匹配规则

鳄鱼君

发表文章数:615

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python » Django框架实现字典循环 路由系统中的正则匹配规则

前面几篇文章我们知道django可以处理特殊字符,我们可以在html页面中添加for循环,只不过是list列表的循环,那么换成一个字典如何获取字典的键和值呢?

假设现在views.py文件中定义一个字典,而不是前面的列表,设置一个index的URL路由系统,让用户在index页面就可以看到views.py中字典的值。首先是views.py文件:

from django.shortcuts import render
from django.views import View

USER_DICT={
    '1':{'name':'鳄鱼君1','email':'1231@qq.com'},
    '2':{'name':'鳄鱼君2','email':'1232@qq.com'},
    '3':{'name':'鳄鱼君3','email':'1233@qq.com'},
    '4':{'name':'鳄鱼君4','email':'1234@qq.com'},
    '5':{'name':'鳄鱼君5','email':'1235@qq.com'},
}
class Index(View):
    #如果GET请求执行get方法
    def get(self,request):
        print(request.method)
        return render(request, 'index.html',{'USER_DICT':USER_DICT})

index.html页面我只贴出循环的代码:

<body>
<ul>
    {% for i in USER_DICT %}  {# 循环字典 i是key #}
    <li>{{ i }}</li>
    {% endfor %}
</ul>
</body>

前面的配置不在详细说明。我们发现这样循环的结果是key值,在Python字典的循环中,存在keys()方法获取键,values()方法获取值,items()两者都可以获取,在django中也可以使用同样的方法,只不过去掉了括号,就是keys,values,items,这个可以自己分别进行尝试。

<body>
<ul>
    {% for k,v in USER_DICT.items %}  {# 循环字典 i是key #}
    <li><a >{{ k }}-{{ v }}</a></li>
    {% endfor %}
</ul>
</body>

这样我们就可以同时把键和值同时拿到,但是我们不希望这样,可以这样想,跟查看详情数据一样,我们只希望显示键,通过键可以进入到详情页查看值。我们创建一个detail.html页面用来展示详情页的数据,也就是显示键对应的值。我们先来修改index.py文件:

<ul>
    {% for k,v in USER_DICT.items %}  {# 循环字典 i是key #}
    <li><a href="/detail/?pid={{ k }}" target="_blank" rel="noopener noreferrer">{{ k }}</a></li>
    {% endfor %}
</ul>

那么详情页的URL就是:http://127.0.0.1:8000/detail/?pid=k,用户点击就会进入详情页detail.html,我们创建一个detail.html,然后修改views.py文件:

from django.shortcuts import render
from django.views import View
USER_DICT={
    '1':{'name':'鳄鱼君1','email':'1231@qq.com'},
    '2':{'name':'鳄鱼君2','email':'1232@qq.com'},
    '3':{'name':'鳄鱼君3','email':'1233@qq.com'},
    '4':{'name':'鳄鱼君4','email':'1234@qq.com'},
    '5':{'name':'鳄鱼君5','email':'1235@qq.com'},
}
class Index(View):
    #如果GET请求执行get方法
    def get(self,request):
        print(request.method)
        return render(request, 'index.html',{'USER_DICT':USER_DICT})
def detail(request):
    pid=request.GET.get('pid')
    detail_info=USER_DICT[pid]
    return render(request,'detail.html',{'detail_info':detail_info})

detail.py部分信息:

<strong >详情页数据</strong>
<strong>用户名:{{ detail_info.name }}</strong>
<strong>邮箱:{{ detail_info.email }}</strong>

这样我们就实现了,在index点击k值,会进入detail详情页显示v值,实现了用户查看详情页的效果。通过这种方式我们就可以实现用户管理页面,首页显示用户,点击用户进入了详情页,可以查看部分信息,这是一样的效果,只不过需要对信息做一下处理,两者本质上是一样的。

通常我们浏览网页就会发现URL是有规律的,不想我们上面定义的这样:http://127.0.0.1:8000/detail/?pid=k,一般都会以html结尾,这样有助于搜索引擎抓取,就像鳄鱼君的文章页面一样显示的是:https://www.e1yu.com/9503.html,这样的样式。那么我们就需要对URL进行配置,可以使用正则表达式,修改urls.py文件:

from django.contrib import admin
from django.conf.urls import url
from myapp import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/',views.Index.as_view()) , #执行类的as_view()方法,固定的用法
    url(r'^detail-(\d+).html/',views.detail), #这里可以进行正则匹配
]

index.html

<ul>
    {% for k,v in USER_DICT.items %}  {# 循环字典 i是key #}
    <li><a href="/detail-{{ k }}.html" target="_blank" rel="noopener noreferrer">{{ k }}</a></li>
    {% endfor %}
</ul>

views.py

class Index(View):
    #如果GET请求执行get方法
    def get(self,request):
        return render(request, 'index.html',{'USER_DICT':USER_DICT})
def detail(request,pid):  #pid为k
    #return HttpResponse(pid)
    detail_info=USER_DICT[pid]
    return render(request,'detail.html',{'detail_info':detail_info})

通过这种方式我们可以从首页:http://127.0.0.1:8000/index/,点击对应的键值,就可以进入到详情页查看值:http://127.0.0.1:8000/detail-2.html/,URL的结构看起来更加合理规范。

鳄鱼君测试的Django版本为3.0.5,在进行正则匹配的时候,还是按照path()的写法,尝试了很多次,一直都是page not found错误,找不到这类:detail-2.html页面,所以更换为url()可以成功找到页面,当然在这里还可以使用下面的这种方式:

from django.contrib import admin
from django.urls import re_path
from myapp import views
urlpatterns = [
    re_path('dmin/', admin.site.urls),
    re_path('index/',views.Index.as_view()) , #执行类的as_view()方法,固定的用法
    re_path('detail-(\d+).html/',views.detail),
]

如果需要对url进行正则匹配的话,推荐使用re_path方法,而不是使用url。在detail函数中有两个形参,一个reqeust,一个pid,这个pid就是detail-(\d+)匹配的数字,那么我们想要把详情页的URL地址修改为detail-1-1.html呢?也就是路由规则修改为:detail-(\d+)-(\d+).html/,这样我们的detail函数就会取到两个值,所以你的detail函数就需要再加一个参数也就是detail(reqeust,pid,nid),否则就会因为参数的数量问题报错:detail() takes 2 positional arguments but 3 were given,这个你自行尝试触发,修改index.html:href=”/detail-{{ k }}-{{ k }}.html”,路由规则:re_path(‘detail-(\d+)-(\d+).html/’,views.detail),detail函数不变,还是两个参数,这样运行django程序就会报参数的错误,解决这个问题只需要在detail穿个参数就可以了,可以不使用,但是必须要保证形参一致,不然就会报错。

detail函数如果写成detail(reqeust,nid,pid),pid和nid顺序调换了,那么在接受的时候就会存在误差。形参顺序调换,在处理的时候就会受到影响,这时候后为了避免这种问题,在正则中可以使用分组:detail-(?P\d+)-(?P\d+).html/,正则表达式没有修改,只是在里面添加了一个?P,这样在进行正则匹配的时候,永远只会将第一个匹配成功的数字赋值给pid,第二个匹配成功的数字赋值给nid,那么在传递给detail函数的时候,就相当于默认参数:detail(request,pid=,nid=)这种方式。

具体的修改和演示不在详细说明,自行尝试。对于这篇文章,鳄鱼君对一些重点内容做了一下整理:django路由规则知识点总结,有兴趣或者不理解的可以去看看!

– END –

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Django框架实现字典循环 路由系统中的正则匹配规则》 发布于2020-04-10

分享到:
赞(3) 赏杯咖啡

评论 抢沙发

1 + 9 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册