#yyds干货盘点#菜谱系统小成阶段,Python Web 领域终于攻占一个小山头

君不见长松卧壑困风霜,时来屹立扶明堂。这篇文章主要讲述#yyds干货盘点#菜谱系统小成阶段,Python Web 领域终于攻占一个小山头相关的知识,希望能为你提供帮助。
十、菜谱的添加与展示本篇博客将进行菜谱系统的核心模块开发,菜谱的添加与展示。
10.1 添加菜谱在 Django 中对于一个功能的实现,添加一定是必备的,没有数据就没有办法进行后续操作了。
实现该功能的第一步依旧是在模板文件夹中添加 html 页面。本页面对于口味,工艺需要调用 API 数据进行渲染,本阶段不做调整。

% extends "menuapp/frame.html" % % block title % 菜谱系统 ---- 添加菜谱 % endblock % % block content % < div class="container"> < h2 class="form-signup-heading"> 添加菜谱< /h2> < div class="well"> < /div> < form class="form-horizontal" role="form" method="post"> % csrf_token % < div class="form-group"> < label for="name" class="col-sm-2 control-label"> 名称:< /label> < div class="col-sm-6"> < input type="text" class="form-control" id="name" name="name" placeholder="请输入菜谱名称" /> < /div> < /div> < div class="form-group"> < label for="technology_sel" class="col-sm-2 control-label"> 工艺:< /label> < div class="col-sm-6"> < select name="technology" class="form-control" id="technology_sel"> < option> 炒< /option> < option> 煮< /option> < option> 烤< /option> < option> 蒸< /option> < /select> < /div> < /div> < div class="form-group"> < label for="flavor_sel" class="col-sm-2 control-label"> 口味:< /label> < div class="col-sm-6"> < select name="flavor" class="form-control" id="flavor_sel"> < option> 家常< /option> < option> 香辣< /option> < option> 怪味< /option> < option> 黑椒< /option> < /select> < /div> < /div> < div class="form-group"> < label for="difficulty" class="col-sm-2 control-label"> 难度:< /label> < div class="col-sm-6"> < select name="difficulty" class="form-control" id="difficulty"> < option value="https://www.songbingjia.com/android/1"> 初级< /option> < option value="https://www.songbingjia.com/android/2"> 中级< /option> < option value="https://www.songbingjia.com/android/3"> 高级< /option> < /select> < /div> < /div> < div class="form-group"> < label for="production_time_sel" class="col-sm-2 control-label" > 时间:< /label > < div class="col-sm-6"> < select name="production_time" class="form-control" id="production_time_sel" > < option value="https://www.songbingjia.com/android/5"> 5分钟< /option> < option value="https://www.songbingjia.com/android/10"> 10分钟< /option> < option value="https://www.songbingjia.com/android/15"> 15分钟< /option> < option value="https://www.songbingjia.com/android/30"> 30分钟< /option> < /select> < /div> < /div> < div class="form-group"> < div class="col-sm-offset-2 col-sm-6"> < button type="submit" class="btn btn-lg btn-primary btn-block"> 确定添加 < /button> < /div> < /div> < /form> < /div> % endblock %

add.html 添加完毕,接下来在对 views.py 文件进行补充,完善该页面的调用。
# 菜谱添加 @user_passes_test(lambda u: u.is_staff) def add_menu(request): user = request.user state = None # 当用户点击确认添加按钮时候的操作 if request.method == "POST": n_menu = Menu( name=request.POST.get("name", ""), technology=request.POST.get("technology", ""), flavor=request.POST.get("flavor", ""), difficulty=request.POST.get("difficulty", ""), production_time=request.POST.get("production_time", "") ) n_menu.save() state = "success"context = "active_menu": add_menu, "user": user, "state": statereturn render(request, "menuapp/add_menu.html", context)

注意该函数上部存在一个装饰器,主要用于判断当前登录的用户是否是超级管理员,否则没有权限操作。使用该装饰器,需要在头部导入相关函数。
from .models import Menu from django.contrib.auth.decorators import user_passes_test

此时,访问 http://127.0.0.1:8000/add 页面,URL 会自动跳转到 http://127.0.0.1:8000/login/?next=/add/ 页面,注意这里遇到了之前埋下的雷,也就是旧 BUG,我们在编制路由的之后,没有考虑带参数的场景,所以接下来修改 urls.py 代码如下,修改的内容差异你可以自行比对。
from django.urls import path from . import viewsurlpatterns = [ path("", views.index, name="default"), path("register/", views.register, name="register"), path("login/", views.login, name="login"), path("logout/", views.logout, name="logout"), path("add/", views.add_menu, name="add_menu") ]

此时编译代码,得到如下界面,表示本步骤已经操作完成。
#yyds干货盘点#菜谱系统小成阶段,Python Web 领域终于攻占一个小山头

文章图片

写到这里需要对 login 函数进行一下完善,因为该视图可能处理两种情况,第一种登录之后跳转首页,第二种是登录之后跳转到登录前的页面。修改代码部分如下:
if user is not None: auth.login(request, user) # 获取 next 指向的地址,如果存在就跳转到 next 指向的地址 target_url = request.GET.get("next", reverse("default"))return HttpResponseRedirect(target_url)

接下来实现注册用户的同时,添加管理员权限,该权限字段由 is_staff 来控制。修改 register.html 页面,修改的代码部分如下所示:
< div class="form-group"> < label for="master" class="col-sm-2 control-label"> 权限:< /label> < div class="col-sm-6"> < div class="checkbox"> < label> < input type="checkbox" name="is_staff" id="master" /> 管理员 < /label> < /div> < /div> < /div>

继续修改 views.py 文件,重点在函数头部编写了一个复选框数据转换字典,然后通过前台传递到视图的数据进行转换:
def register(request): CHECKBOX_MAPPING = on: True, off: False, if request.user.is_authenticated: return HttpResponseRedirect(reverse("default"))# 用户注册状态信息 state = None # 当用户提交注册信息 if request.method == "POST": username = request.POST.get("username", "") password = request.POST.get("password", "") email = request.POST.get("email", "") is_staff = CHECKBOX_MAPPING[request.POST.get("is_staff", "off")]# 判断用户名是否存在 if User.objects.filter(username=username): state = "user_exist"else: n_user = User.objects.create_user(username=username, password=password, email=email, is_staff=is_staff) # 保存注册信息到数据库 n_user.save() state = "success"# 表示注册成功context = "active_menu": default, "user": None, "state": statereturn render(request, "menuapp/register.html", context)

当上述代码运行成功之后,再通过 register.html 页面注册的同时,可以勾选管理员身份,注册到数据库中的数据如下。
#yyds干货盘点#菜谱系统小成阶段,Python Web 领域终于攻占一个小山头

文章图片

截止到现在,如果你整体步骤都梳理清楚之后,就已经实现登录之后才可以访问添加菜谱页面的 Web 应用了。
备注,如果非管理员访问 add/ 会自动跳转回首页。
10.2 菜谱列表优先实现一个最简单的列表页面,在读取菜谱数据的时候,为防止出现一次性读取大量数据,所以需要使用投影方法,读取部分数据字段。
views.py 新增 menu_list 函数,该函数要求用户登录状态下才可以访问,在文件开头注意导入对应的函数。
from django.contrib.auth.decorators import user_passes_test, login_required from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage# 分页组件@login_required def menu_list(request): user = request.usermenus = Menu.objects.all()# 数据分页 paginator = Paginator(menus, 10) page = request.GET.get("page") # 分页异常处理 try: menus = paginator.page(page) except PageNotAnInteger: menus = paginator.page(1) except EmptyPage: menus = paginator.page(paginator.num_pages)context = "user": user, "active_menu": "view_menu", "menu_list": menusreturn render(request, "menuapp/list.html", context)

本函数实现了基本的分页功能,但是对菜谱的分类功能,还未实现,后文继续对其进行补充说明。实现了 menu_list 函数之后,立刻对 urls.py 文件进行修改。
urlpatterns = [ path("", views.index, name="default"), path("register/", views.register, name="register"), path("login/", views.login, name="login"), path("logout/", views.logout, name="logout"), path("add/", views.add_menu, name="add_menu"), path("list/", views.menu_list, name="menu_list") ]

准备工作已经完成,在 templates/menuapp 中新增文件 list.html,添加如下代码,该代码中使用了部分模板语言。
% extends "menuapp/frame.html" % % block title % 菜谱系统 ---- 列表页面 % endblock % % block content % < div class="container"> < div class="row"> < div class="col-md-10 col-md-offset-1"> < div class="col-md-2"> < div class="list-group"> < a rel="nofollow" href="https://www.songbingjia.com/android/% url menu_list%"> 全部菜谱< /a> < !--后期处理成菜谱分类--> < /div> < /div> < div class="col-md-9 col-md-offset-1"> < table class="table table-hover"> < thead> < tr> < th> #< /th> < th> 菜谱名称< /th> < th> 工艺< /th> < th> 口味< /th> < th> 难度< /th> < th> 时间< /th> < /tr> < /thead> < tbody> % for menu in menu_list % < tr> < td> forloop.counter< /td> < td> menu.name < /td> < td> menu.technology < /td> < td> menu.flavor < /td> < td> menu.difficulty < /td> < td> menu.production_time < /td> < /tr> % endfor % < /tbody> < /table> < nav> < ul class="pager"> % if menu_list.has_previous % < li class="previous"> < a href="https://www.songbingjia.com/android/% url menu_list %?page= menu_list.previous_page_number" > 上一页< /a > < /li> % else % < li class="previous disabled"> < a rel="nofollow" href="https://www.songbingjia.com/android/#"> 上一页< /a> < /li> % endif % 第menu_list.number/ menu_list.paginator.num_pages页 % if menu_list.has_next % < li class="next"> < a href="https://www.songbingjia.com/android/% url menu_list %?page= menu_list.next_page_number" > 下一页< /a > < /li> % else % < li class="next disabled"> < a rel="nofollow" href="https://www.songbingjia.com/android/#"> 下一页< /a> < /li> % endif % < /ul> < /nav> < /div> < /div> < /div> < /div> % endblock %

最终实现初稿效果如下,一个包含分页的菜谱系统列表页面已经完成。
#yyds干货盘点#菜谱系统小成阶段,Python Web 领域终于攻占一个小山头

文章图片

10.3 本篇博客小节【#yyds干货盘点#菜谱系统小成阶段,Python Web 领域终于攻占一个小山头】本篇博客对菜谱系统的菜谱添加、列表以及分页功能,一个微型的菜谱管理系统已经初具模型,后续都是对其进行完善与修改,希望你能在本篇博客学到知识,感谢。

    推荐阅读