菜谱系统小成阶段,Python Web 领域终于攻占一个小山头

梦想橡皮擦 2021-04-07 14:39:18
系统 阶段 小成 菜谱 谱系


橡皮擦,一个逗趣的互联网高级网虫。新的系列,让我们一起进入 Django 世界。

已经完成的文章

十、菜谱的添加与展示

本篇博客将进行菜谱系统的核心模块开发,菜谱的添加与展示。

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="1">初级</option>
<option value="2">中级</option>
<option value="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="5">5分钟</option>
<option value="10">10分钟</option>
<option value="15">15分钟</option>
<option value="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": state
}
return 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 views
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")
]

此时编译代码,得到如下界面,表示本步骤已经操作完成。

Python Django 阶段性小目标 -- 菜谱系统小有所成
写到这里需要对 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": state
}
return render(request, "menuapp/register.html", context)

当上述代码运行成功之后,再通过 register.html 页面注册的同时,可以勾选管理员身份,注册到数据库中的数据如下。

Python Django 阶段性小目标 -- 菜谱系统小有所成
截止到现在,如果你整体步骤都梳理清楚之后,就已经实现登录之后才可以访问添加菜谱页面的 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.user
menus = 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": menus
}
return 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 href="{% 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="{% url 'menu_list' %}?page={
{ menu_list.previous_page_number }}"
>上一页</a
>
</li>
{% else %}
<li class="previous disabled">
<a href="#">上一页</a>
</li>
{% endif %} 第 {
{ menu_list.number }} / {
{
menu_list.paginator.num_pages }} 页 {% if menu_list.has_next %}
<li class="next">
<a
href="{% url 'menu_list' %}?page={
{ menu_list.next_page_number }}"
>下一页</a
>
</li>
{% else %}
<li class="next disabled">
<a href="#">下一页</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</div>
</div>
</div>
{% endblock %}

最终实现初稿效果如下,一个包含分页的菜谱系统列表页面已经完成。

Python Django 阶段性小目标 -- 菜谱系统小有所成

10.3 本篇博客小节

本篇博客对菜谱系统的菜谱添加、列表以及分页功能,一个微型的菜谱管理系统已经初具模型,后续都是对其进行完善与修改,希望你能在本篇博客学到知识,感谢。

相关阅读

  1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧
  2. Python 游戏世界(更新中,目标文章数 50+,现在订阅,都是老粉)
  3. Python 爬虫小课,精彩 9 讲

今天是持续写作的第 128 / 200 天。
如果你想跟博主建立亲密关系,可以关注同名公众号 梦想橡皮擦,近距离接触一个逗趣的互联网高级网虫。
博主 ID:梦想橡皮擦,希望大家点赞评论收藏

django教程 django中文文档 Django 文档 django需要什么基础 第一个django项目 django建站教程 django框架怎么使用 django组件 在django中创建项目
版权声明
本文为[梦想橡皮擦]所创,转载请带上原文链接,感谢
https://blog.csdn.net/hihell/article/details/115459196

  1. 安装python
  2. 按尺寸切片pandas数据集DataFrame到多个文件
  3. Install Python
  4. Slice the pandas dataset dataframe to multiple files by size
  5. python 求最大值、最小值、平均值
  6. Finding maximum, minimum and average in Python
  7. 认识Python解释器和PyCharm编辑器
  8. Know Python interpreter and pycharm editor
  9. Python 小数据池和代码块缓存机制
  10. Python small data pool and code block caching mechanism
  11. python刷题-序列求和
  12. python刷题-圆的面积
  13. Sequence summation in Python
  14. The area of a circle
  15. Python functions, advanced syntax and usage
  16. Teach you to crawl novels in Python! Who can pay for novels these days!
  17. Python入门学习之:10分钟1500访问量
  18. Introduction to Python: 1500 visits in 10 minutes
  19. 数据分析之Pandas合并操作总结
  20. OpenCV-Python 雪花飘落特效
  21. Pandas merge operation summary of data analysis
  22. Opencv Python snowflake falling effect
  23. python logging模块“另一个程序正在使用此文件,进程无法访问。”问题解决办法
  24. Python logging module "this file is being used by another program and cannot be accessed by the process." Problem solving
  25. Mac 下python3 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 解决方法
  26. Python 3 [SSL: Certificate] on MAC_ VERIFY_ Failed] certificate verify failed solution
  27. Python学习之解决python下载第三方依赖速度慢的问题
  28. Python learning to solve the problem of slow download speed of third party dependence on Python
  29. python操作Excel文件报lrd.biffh.XLRDError
  30. How to operate excel file with Python lrd.biffh.XLRDError
  31. 2021的挑战与机遇,今年Python数据分析岗位会很香!
  32. The challenge and opportunity of 2021, python data analysis post will be very popular this year!
  33. 【C++简明教程】Python和C++指定元素排序比较
  34. Comparison of Python and C + + specified element sorting
  35. Python Flask使用Nginx做代理时如何获取真实IP
  36. How to get real IP address when Python flash uses nginx as proxy
  37. Python培训出来好找工作吗?好找工作的关键是什么?
  38. Is Python training easy to find a job? What is the key to finding a good job?
  39. 从零开始学python | 什么是Python JSON?
  40. Learn Python from scratch | what is Python JSON?
  41. 用 Python 读写 Excel 表格
  42. Python装饰器高级用法
  43. Reading and writing excel table with Python
  44. Python decorator advanced usage
  45. 从零开始学python | 什么是Python JSON?
  46. Learn Python from scratch | what is Python JSON?
  47. Python with关键字原理详解
  48. Python with keyword principle
  49. python + uiautomator2 实现钉钉工单提交
  50. 一个神级般的 Python 调试神器
  51. Nail work order submission based on Python + uiautomator2
  52. A magic Python debugging artifact
  53. 从零开始学python | 什么是Python JSON?
  54. Learn Python from scratch | what is Python JSON?
  55. 上手Pandas,带你玩转数据(3)-- pandas数据存入文件
  56. Start pandas, take you to play with data (3) -- save pandas data into file
  57. Python能代替shell吗?有什么特点?
  58. Can Python replace shell? What are the features?
  59. Scikit-learn 机器学习库介绍!【Python入门】
  60. Scikit learn machine learning library introduction! [introduction to Python]