八、全局搜索和全局错误页面配置
1.index.html页面的完善(轮播图)2.搜索功能开发3.url跳转的修改4.Django验证-自定义用户查询5.Django错误显示页面配置
八、全局搜索和全局错误页面配置 1.index.html页面的完善(轮播图)设置轮播图:
在apps/operations/models.py中:
# 省略
UserProfile = get_user_model()
# 轮播图
class Banner(baseModel):
title = models.CharField(max_length=100, verbose_name="标题")
image = models.ImageField(upload_to="banner/%Y/%m", max_length=200, verbose_name="轮播图")
url = models.URLField(max_length=200, verbose_name="访问地址")
index = models.IntegerField(default=0, verbose_name="顺序")
class meta:
verbose_name = "轮播图"
verbose_name_plural = verbose_name
def __str__(self):
return self.title
# 用户咨询
# 省略
设置字段确定是否为广告位课程:
在apps/courses/models.py中:
# 省略
# 继承baseModel
# 课程
class Course(baseModel):
# 省略
# 显示富文本,TextField不限制长度
detail = models.TextField(verbose_name="课程详情")
# 是否为广告位课程
is_banner = models.BooleanField(default=False, verbose_name="是否广告位")
image = models.ImageField(upload_to="courses/%Y/%m", verbose_name="封面图", max_length=100)
# 省略
菜单栏-Tools-Run manage.py Task
makemigrations
migrate
在apps/operations/views.py中:
# 省略
from apps.operations.models import Banner
# Create your views here.
# 首页
class IndexView(View):
def get(self, request, *args, **kwargs):
banners = Banner.objects.all().order_by("index")
# 将轮播图中已取出的课程进行过滤
courses = Course.objects.filter(is_banner=False)[:6]
# 轮播图课程
banner_courses = Course.objects.filter(is_banner=True)
course_orgs = CourseOrg.objects.all()[:15]
return render(request, "index.html",{
"banners": banners,
"courses": courses,
"banner_courses": banner_courses,
"course_orgs": course_orgs
})
# 课程评论
# 省略
在apps/users/views.py中:
# 动态验证码的登录
class DynamicLoginView(View):
def get(self, request, *args, **kwargs):
if request.user.is_authenticated:
return HttpResponseRedirect(reverse("index"))
next = request.GET.get("next", "")
login_form = DynamicLoginForm()
banners = Banner.objects.all()[:3]
return render(request, "login.html", {
"login_form": login_form,
"next": next,
"banners": banners
})
def post(self, request, *args, **kwargs):
login_form = DynamicLoginPostForm(request.POST)
dynamic_login = True
banners = Banner.objects.all()[:3]
if login_form.is_valid():
# 设置没有注册账号仍然可以登录
# 先查询用户是否存在
mobile = login_form.cleaned_data["mobile"]
existed_users = UserProfile.objects.filter(mobile=mobile)
if existed_users:
user = existed_users[0]
else:
# 用户不存在,新建用户
# 用户名为必填字段,用手机号填充
user = UserProfile(username=mobile)
# 此时用户未输入密码,可以进行密码的生成,生成10位
password = generate_random(10, 2)
# 密码为加密的,不能直接赋值明文,使用set_password方法进行密码的加密
user.set_password(password)
# 填入必填字段手机号
user.mobile = mobile
user.save()
# 进行登录
login(request, user)
# 如果有next跳转到next,若没有则跳转到首页
next = request.GET.get("next", "")
if next:
return HttpResponseRedirect(next)
# 跳转到首页
return HttpResponseRedirect(reverse("index"))
else:
d_form = DynamicLoginForm()
return render(request, "login.html", {"login_form": login_form,
"d_form": d_form,
"banners": banners,
"dynamic_login": dynamic_login})
# 省略
# 用户登录
# 继承Django内部的View
class LoginView(View):
# 重载get方法,request为django自动注入的参数
# 有可能传递多个参数,设置接受多变量的方式,可以点入View中从def dispatch中的return中查看源码
def get(self, request, *args, **kwargs):
# 在index.html已经判断了用户是否登录,获取此属性is_authenticated
if request.user.is_authenticated:
# 如果已经是登录状态,重定向到首页
return HttpResponseRedirect(reverse("index"))
banners = Banner.objects.all()[:3]
next = request.GET.get("next", "")
# 进行实例化
login_form = DynamicLoginForm()
return render(request, "login.html", {
# 将变量传递进html中
"login_form": login_form,
"next": next,
"banners": banners
})
# 用户数据的获取
def post(self, request, *args, **kwargs):
# 省略
# 未查询到用户,要将login_form传递回去,保留用户输入的错误的用户名和密码在页面上
return render(request, "login.html", {"msg": "用户名或密码错误", "login_form": login_form, "banners": banners})
else:
return render(request, "login.html", {"login_form": login_form,
"banners": banners})
在MxOnline/urls.py中:
# 省略
from MxOnline.settings import MEDIA_ROOT
from apps.operations.views import IndexView
urlpatterns = [
# path('admin/', admin.site.urls),
path('xadmin/',xadmin.site.urls),
# # 设置直接访问域名的时候直接到此页面
# path('', TemplateView.as_view(template_name="index.html"), name="index"),
# 首页
path('', IndexView.as_view(), name="index"),
# 在此处login后要加/,解决访问时http://127.0.0.1:8000/login后面多加/出现的Page not found的问题
# path('login/', TemplateView.as_view(template_name="login.html"), name= "login")
path('login/', LoginView.as_view(), name= "login"),
# 注册
# 省略
在templates/index.html中:
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}首页-慕学在线网{% endblock %}
{% block content %}
公开课程
{% for course in courses %}
{{ course.name }}
难度:{{ course.get_degree_display }}
学习人数:{{ course.students }}
{{ course.course_org.name }}
{{ course.fav_nums }}
{% endfor %}
课程机构
{% for org in course_orgs %}
-
{{ org.tag }}
{{ org.name }}
{% endfor %}
{% endblock %}
{% block custom_js %}
{% endblock %}
可在后台管理系统中的课程信息中设置是否为广告位,显示的是公开课程位置的轮播。
轮播图管理器:
在apps/operations/adminx.py中:
# 省略
class UserAskAdmin(object):
# 省略
class BannerAdmin(object):
list_display = ['title', 'image', 'url', "index"]
search_fields = ['title', 'image', 'url', "index"]
list_filter = ['title', 'image', 'url', "index"]
class UserCourseAdmin(object):
# 省略
# 省略
xadmin.site.register(UserAsk, UserAskAdmin)
xadmin.site.register(Banner, BannerAdmin)
xadmin.site.register(UserCourse, UserCourseAdmin)
# 省略
在后台管理系统中的轮播图中可对顶端的轮播图进行管理。
2.搜索功能开发在apps/courses/views.py中:
# 省略
from django.db.models import Q
from apps.courses.models import Course, CourseTag, CourseResource, Video
# 省略
# 获取课程列表信息
class CourseListView(View):
def get(self, request, *args, **kwargs):
# 根据添加时间进行倒序排列,最新的放在最前面
all_courses = Course.objects.order_by("-add_time")
# 右边栏,热门课程的展示,进行切片只展示前3个
hot_courses = Course.objects.order_by("-click_nums")[:3]
# 搜索关键词
keywords = request.GET.get("keywords", "")
s_type = "course"
if keywords:
# name__icontains前面的i代表不区别大小写,使用Q来进行语句的组装,使得任何一个字段出现keywords都可以被搜索
all_courses = all_courses.filter(Q(name__icontains=keywords) | Q(desc__icontains=keywords) | Q(desc__icontains=keywords))
# 课程排序
# 省略
return render(request, "course-list.html", {
"all_courses": courses,
"sort": sort,
"hot_courses": hot_courses,
"keywords": keywords,
"s_type": s_type
})
在apps/organizations/views.py中:
# 讲师列表页面
class TeacherListView(View):
def get(self, request, *args, **kwargs):
all_teachers = Teacher.objects.all()
teacher_nums = all_teachers.count()
hot_teachers = Teacher.objects.all().order_by("-click_nums")[:3]
# 搜索关键词
keywords = request.GET.get("keywords", "")
s_type = "teacher"
if keywords:
all_teachers = all_teachers.filter(Q(name__icontains=keywords))
# 对讲师进行排序
# 省略
return render(request, "teachers-list.html", {
"teachers": teachers,
"teacher_nums": teacher_nums,
"sort": sort,
"hot_teachers": hot_teachers,
"keywords": keywords,
"s_type": s_type
})
# 省略
class OrgView(View):
def get(self, request, *args, **kwargs):
# 从数据库中获取数据
all_orgs = CourseOrg.objects.all()
all_citys = City.objects.all()
# 根据点击数进行机构排序,右边栏广告位有限,做切片
hot_orgs = all_orgs.order_by("-click_nums")[:3]
# 搜索关键词
keywords = request.GET.get("keywords", "")
s_type = "org"
if keywords:
all_orgs = all_orgs.filter(Q(name__icontains=keywords) | Q(desc__icontains=keywords))
# 通过机构类别对课程机构进行筛选,参数名称ct和html中对应
# 省略
return render(request, "org-list.html", {
"all_orgs": orgs,
"org_nums": org_nums,
"all_citys": all_citys,
"category": category,
"city_id": city_id,
"sort": sort,
"hot_orgs": hot_orgs,
"keywords": keywords,
"s_type": s_type
})
在templates/base.html中(61行):
3.url跳转的修改
Edit-Find-Find in Path,选择html文件,搜索href=
在templates/course-comment.html中:
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}课程章节信息-慕学在线网{% endblock %}
{% block custom_css%}
{% endblock %}
{% block custom_bread %}
{% endblock %}
{% block content %}
{{ course.name }}
{{ course.get_degree_display }}
难度
{{ course.learn_times }}分钟
时长
{{ course.students }}
学习人数
{% endblock %}
{% block custom_js %}
{% endblock %}
在templates/course-play.html中:
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}课程章节信息-慕学在线网{% endblock %}
{% block custom_css%}
{% endblock %}
{% block custom_js %}
{% endblock %}
{% block custom_bread %}
- 首页">>
- 公开课">>
- {{ course.name }}">>
- 课程详情">>
- 章节信息
{% endblock %}
{% block content %}
{% endblock %}
在templates/course-video.html中:
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}课程章节信息-慕学在线网{% endblock %}
{% block custom_css%}
{% endblock %}
{% block custom_bread %}
{% endblock %}
{% block content %}
{{ course.name }}
{{ course.get_degree_display }}
难度
{{ course.learn_times }}分钟
时长
{{ course.students }}
学习人数
{% endblock %}
在templates/login.html中:
{% load staticfiles %}
慕学在线网登录
慕学在线网,在线学习平台!
在templates/org-detail-course.html中:(8行)
{% for course in all_courses.object_list %}![]()
{{ course.name }}
在templates/org-detail-homepage.html中:(13行)
![]()
{{ course.name }}
在templates/org-detail-teachers.html中:(13行)
![]()
{{ teacher.name }}已认证
在templates/org-list.html中:(84行)
经典课程: {% if org.courses %} {% for course in org.courses %} {{ course.name }} {% endfor %} {% else %} 无 {% endif %} 294行:
- {{ forloop.counter }}
{{ org.name }}
{{ org.address }}
在templates/teacher-detail.html中:(64行)
![]()
{{ course.name }}
时长:{{ course.learn_times }} 学习人数:{{ course.students }}{{ course.course_org.name }} {{ course.fav_nums }}在templates/usercenter-base.html中:
{% load staticfiles %}{% block title %}个人信息- 慕学在线网{% endblock %} {% block custom_css %} {% endblock %}{% block custom_bread %} {% endblock %} {% block custom_js %} {% endblock %} 在templates/usercenter-mycourse.html中:(33行)
{{ user_course.course.name }}
课程详情页中学习用户的展示的完善:
在templates/course-detail.html中:(39行)
学习用户: {% for user_course in course.usercourse_set.all|slice:3 %} 4.Django验证-自定义用户查询{% endfor %}
之前在apps/users/views.py中:
# 用户登录 # 继承Django内部的View class LoginView(View): # 省略 # 用户数据的获取 def post(self, request, *args, **kwargs): # 省略 user = authenticate(username=user_name, password=password)在post表单验证完成后,调用了authenticate方法,传递用户名和密码后验证账户名是否合法。
在apps/users/views.py中:
# 省略 from pure_pagination import Paginator, PageNotAnInteger from django.contrib.auth.backends import ModelBackend from django.db.models import Q from apps.users.forms import LoginForm, DynamicLoginForm, DynamicLoginPostForm, UploadImageForm # 省略 # 自定义用户验证 class CustomAuth(ModelBackend): # 重载方法,会将之前在LoginView中的username和password传递进来 def authenticate(self, request, username=None, password=None, **kwargs): try: # 进行查询 user = UserProfile.objects.get(Q(username=username)|Q(mobile=username)) # 如果查询到用户,验证密码是否正确 if user.check_password(password): return user # 未查询到 except Exception as e: return None此类需要配置到settings中:
在MxOnline/settings.py中:
# 省略 ALLOWED_HOSTS = [] # Application definition AUTHENTICATION_BACKENDS = [ "apps.users.views.CustomAuth" ] INSTALLED_APPS = [ # 省略5.Django错误显示页面配置将403.html、404.html、500.html页面拷贝到templates文件夹下
配置静态文件:
在templates/403.html中:
403 在templates/404.html中:
404 在templates/500.html中:
500 以下改动只是演示错误页面的显示,之后本节以下改动的代码全部注释掉。
在MxOnline/settings.py中:
# 省略 # SECURITY WARNING: don't run with debug turned on in production! # 设置为False,便不会进行静态文件的代理 DEBUG = False # 配置哪些IP可以访问,*代表所有IP均可访问 ALLOWED_HOSTS = ['*'] STATIC_URL = '/static/' # # 指明在哪里搜索静态文件,与变量STATIC_ROOT不能同时存在 # STATICFILES_DIRS = [ # # 若有多个搜索目录可以添加到这个list中 # # 使用相对路径 # os.path.join(base_DIR, 'static') # ] # 省略 MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(base_DIR, 'media') # 配置静态文件的访问 STATIC_ROOT = os.path.join(base_DIR, 'static') # 省略在MxOnline/urls.py中:
# 省略 from MxOnline.settings import MEDIA_ROOT from MxOnline.settings import STATIC_ROOT from apps.operations.views import IndexView urlpatterns = [ # 省略 # 配置上传文件访问的url,此正则表达式的意思为:将media后面的所有字符串截取出来放到path变量中 url(r'media/(?P.*)$', serve, {"document_root": MEDIA_ROOT}), # 静态文件配置 url(r'static/(?P .*)$', serve, {"document_root": STATIC_ROOT}), # 机构相关页面 # 省略 在页面输入一个不存在的URL,如http://127.0.0.1:8000/ddd
会出现404页面。
若URL不存在,Django会在templates文件夹下找404.html。
制造500的错误页面:
在apps/operations/views.py中:
# 首页 class IndexView(View): def get(self, request, *args, **kwargs): # 制造500的页面错误 1/0 banners = Banner.objects.all().order_by("index") # 省略运行项目,可看到500的错误页面。
制造403的错误页面:
在apps/operations/views.py中:
# 首页 class IndexView(View): def get(self, request, *args, **kwargs): # # 制造500的页面错误 # 1/0 # 制造403错误页面 from django.core.exceptions import PermissionDenied raise PermissionDenied banners = Banner.objects.all().order_by("index") # 省略运行项目,可看到403的错误页面。
将上述除了页面中的代码都进行还原。
Python相关栏目本月热门文章
- 1【Linux驱动开发】设备树详解(二)设备树语法详解
- 2别跟客户扯细节
- 3Springboot+RabbitMQ+ACK机制(生产方确认(全局、局部)、消费方确认)、知识盲区
- 4【Java】对象处理流(ObjectOutputStream和ObjectInputStream)
- 5【分页】常见两种SpringBoot项目中分页技巧
- 6一文带你搞懂OAuth2.0
- 7我要写整个中文互联网界最牛逼的JVM系列教程 | 「JVM与Java体系架构」章节:虚拟机与Java虚拟机介绍
- 8【Spring Cloud】新闻头条微服务项目:FreeMarker模板引擎实现文章静态页面生成
- 9JavaSE - 封装、static成员和内部类
- 10树莓派mjpg-streamer实现监控及拍照功能调试
- 11用c++写一个蓝屏代码
- 12从JDK8源码中看ArrayList和LinkedList的区别
- 13idea 1、报错java: 找不到符号 符号: 变量 log 2、转换成Maven项目
- 14在openwrt使用C语言增加ubus接口(包含C uci操作)
- 15Spring 解决循环依赖
- 16SpringMVC——基于MVC架构的Spring框架
- 17Andy‘s First Dictionary C++ STL set应用
- 18动态内存管理
- 19我的创作纪念日
- 20Docker自定义镜像-Dockerfile
热门相关搜索路由器设置 木托盘 宝塔面板 儿童python教程 心情低落 朋友圈 vim 双一流学科 专升本 我的学校 日记学校 西点培训学校 汽修学校 情书 化妆学校 塔沟武校 异形模板 西南大学排名 最精辟人生短句 6步教你追回被骗的钱 南昌大学排名 清朝十二帝 北京印刷学院排名 北方工业大学排名 北京航空航天大学排名 首都经济贸易大学排名 中国传媒大学排名 首都师范大学排名 中国地质大学(北京)排名 北京信息科技大学排名 中央民族大学排名 北京舞蹈学院排名 北京电影学院排名 中国戏曲学院排名 河北政法职业学院排名 河北经贸大学排名 天津中德应用技术大学排名 天津医学高等专科学校排名 天津美术学院排名 天津音乐学院排名 天津工业大学排名 北京工业大学耿丹学院排名 北京警察学院排名 天津科技大学排名 北京邮电大学(宏福校区)排名 北京网络职业学院排名 北京大学医学部排名 河北科技大学排名 河北地质大学排名 河北体育学院排名




















