全局导航&个人中心&全局搜索
配置全局导航
让index页面也继承base页面,注意首页有个单独的index.js
base页面的导航栏也进行配置
但是现在我们不知道当前是哪一个页面,因为后端没有传值过来
这里可以使用request.path
进行判断
比如http://127.0.0.1:8000/org/teacher_list/
,则request.path 就是`/org/teacher_list/``
slice:12 是过滤器,取前12位数
利用这种方法可以达到全局的“active”效果,而不用每个子页面都要去设置“active”了
全局搜索功能
通过url中加参数keywords来达到全局搜索的功能
以Course搜索为例:
# 搜索功能
search_keywords = request.GET.get('keywords', '')
if search_keywords:
# icontains是包含的意思(不区分大小写)
# Q可以实现多个字段,之间是or的关系
all_course = all_course.filter(
Q(name__icontains=search_keywords) | Q(desc__icontains=search_keywords) | Q(
detail__icontains=search_keywords))
搜索的代码放在deco-common.js
中
如果自己写的url和js文件中的不同,可自行修改
//顶部搜索栏搜索方法
function search_click(){
var type = $('#jsSelectOption').attr('data-value'),
keywords = $('#search_keywords').val(),
request_url = '';
if(keywords == ""){
return
}
if(type == "course"){
request_url = "/course/list?keywords="+keywords
}else if(type == "teacher"){
request_url = "/org/teacher/list?keywords="+keywords
}else if(type == "org"){
request_url = "/org/list?keywords="+keywords
}
window.location.href = request_url
}
课程机构搜索功能
# 机构搜索功能
search_keywords = request.GET.get('keywords', '')
if search_keywords:
# 在name字段进行操作,做like语句的操作。i代表不区分大小写
# or操作使用Q
all_orgs = all_orgs.filter(Q(name__icontains=search_keywords) | Q(desc__icontains=search_keywords))
授课老师搜索功能
# 搜索功能
search_keywords = request.GET.get('keywords', '')
if search_keywords:
# 在name字段进行操作,做like语句的操作。i代表不区分大小写
# or操作使用Q
all_teachers = all_teacher.filter(name__icontains=search_keywords)
个人中心信息展示
新建usercenter-bae.html
当模板
进行配置
path("users/", include('users.urls', namespace="users")),
from django.urls import path
from users.views import UserinfoView
app_name = 'users'
urlpatterns = [
#用户信息
path("info/", UserinfoView.as_view(),name='user_info'),
]
class UserinfoView(LoginRequiredMixin,View):
'''用户个人信息'''
def get(self,request):
return render(request,'usercenter-info.html',{})
前端显示个人信息
个人信息
修改密码和修改头像
#用户图像上传
path("image/upload/", UploadImageView.as_view(),name='image_upload'),
新建一个用于保存图片的form
这里继承的是ModelForm,该类具有save功能
# 用于文件上传,修改头像
class UploadImageForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['image']
class UploadImageView(LoginRequiredMixin,View):
'''用户图像修改'''
def post(self,request):
# 这时候用户上传的文件就已经被保存到image_form了 ,为modelform添加instance值直接保存
image_form = UploadImageForm(request.POST, request.FILES, instance=request.user)
if image_form.is_valid():
image_form.save()
# 所有验证通过的字段放在cleaned data
# # 取出cleaned data中的值,一个dict
# image = image_form.cleaned_data['image']
# request.user.image = image
# request.user.save()
return HttpResponse('{"status":"success"}', content_type='application/json')
else:
return HttpResponse('{"status":"fail"}', content_type='application/json')
#用户个人中心修改密码
path("update/pwd/", UpdatePwdView.as_view(),name='update_pwd'),
# 在个人中心修改用户密码
class UpdatePwdView(View):
def post(self, request):
modiypwd_form = ModifyPwdForm(request.POST)
if modiypwd_form.is_valid():
pwd1 = request.POST.get("password1", "")
pwd2 = request.POST.get("password2", "")
# 如果两次密码不相等,返回错误信息
if pwd1 != pwd2:
return HttpResponse('{"status":"fail", "msg":"密码不一致"}', content_type='application/json')
# 如果密码一致
user =request.user
# 加密成密文
user.password = make_password(pwd2)
# save保存到数据库
user.save()
return HttpResponse('{"status":"success"}', content_type='application/json')
# 验证失败说明密码位数不够。
else:
return HttpResponse('{"status":"fail", "msg":"填写错误请检查"}', content_type='application/json')
Ajxa代码放在deco-user.js
里面
如果url不正确可自行配置'
如果遇到403,检查base中的csrf_token是否填写
发送修改邮箱验证码
有两个接口需要完成。点击获取验证码时,后台需要向用户新邮箱发送验证码。
邮箱如果出错,会返回错误信息。
输入了邮箱和验证码,验证是否匹配。
给EmailVerifyRecord
再添加一个选择类型
SEND_CHOICES = (
("register", "注册"),
("forget", "找回密码"),
("update_email", "修改邮箱")
)
#发送邮箱验证码
path("sendemail_code/", SendEmailCodeView.as_view(),name='sendemail_code'),
# 发送邮箱验证码view
class SendEmailCodeView(LoginRequiredMixin, View):
def get(self,request):
# 取出需要发送的邮件
email = request.GET.get("email", "")
# 不能是已注册的邮箱
if UserProfile.objects.filter(email=email):
return HttpResponse('{"email":"邮箱已经存在"}', content_type='application/json')
send_register_eamil(email, "update_email")
return HttpResponse('{"status":"success"}', content_type='application/json')
修改utils/email_send.py
if send_type == "update_email":
email_title = "慕课在线 修改邮箱"
email_body = "验证码:{0}".format(code)
# 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者list
send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
# 如果发送成功
if send_status:
pass
修改邮箱
#修改邮箱
path("update_email/", UpdateEmailView.as_view(),name='update_email'),
# 修改邮箱的view:
class UpdateEmailView(LoginRequiredMixin, View):
def post(self, request):
email = request.POST.get("email", "")
code = request.POST.get("code", "")
existed_records = EmailVerifyRecord.objects.filter(email=email, code=code, send_type='update_email')
if existed_records:
user = request.user
user.email = email
user.save()
return HttpResponse('{"status":"success"}', content_type='application/json')
else:
return HttpResponse('{"email":"验证码无效"}', content_type='application/json')
个人信息修改
# 个人中心信息修改
class UserInfoForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['nick_name','gender','birthday','address','mobile']
给UserinfoView
添加post方法
class UserinfoView(LoginRequiredMixin,View):
'''用户个人信息'''
def get(self,request):
return render(request,'usercenter-info.html',{})
def post(self, request):
# 需要指明instance。不然无法修改,而是新增用户
user_info_form = UserInfoForm(request.POST, instance=request.user)
if user_info_form.is_valid():
user_info_form.save()
return HttpResponse('{"status":"success"}', content_type='application/json')
else:
return HttpResponse(json.dumps(user_info_form.errors), content_type='application/json')
我的课程
# 用户中心我的课程
path('mycourse/', MyCourseView.as_view(), name="mycourse"),
# 个人中心页我的课程
class MyCourseView(LoginRequiredMixin, View):
def get(self, request):
user_courses = UserCourse.objects.filter(user=request.user)
return render(request, "usercenter-mycourse.html", {
"user_courses":user_courses,
})
{% block custom_right_content %}
我的课程
{% endblock %}
我的收藏--课程机构
# 我的收藏--课程机构
path('myfav/org/', MyFavOrgView.as_view(), name="myfav_org"),
# 我收藏的课程机构
class MyFavOrgView(LoginRequiredMixin, View):
def get(self, request):
org_list = []
fav_orgs= UserFavorite.objects.filter(user=request.user, fav_type=2)
# 上面的fav_orgs只是存放了id。我们还需要通过id找到机构对象
for fav_org in fav_orgs:
# 取出fav_id也就是机构的id。
org_id = fav_org.fav_id
# 获取这个机构对象
org = CourseOrg.objects.get(id=org_id)
org_list.append(org)
return render(request, "usercenter-fav-org.html", {
"org_list": org_list,
})
我的收藏--授课讲师
Teacher添加一个方法
def get_course_nums(self):
return self.course_set.all().count()
# 我收藏的授课讲师
path('myfav/teacher/', MyFavTeacherView.as_view(), name="myfav_teacher"),
class MyFavTeacherView(LoginRequiredMixin, View):
'''我收藏的授课讲师'''
def get(self, request):
teacher_list = []
fav_teachers = UserFavorite.objects.filter(user=request.user, fav_type=3)
for fav_teacher in fav_teachers:
teacher_id = fav_teacher.fav_id
teacher = Teacher.objects.get(id=teacher_id)
teacher_list.append(teacher)
return render(request, "usercenter-fav-teacher.html", {
"teacher_list": teacher_list,
})
我的收藏--公开课程
#我的收藏--课程
path('myfav/course/', MyFavCourseView.as_view(), name="myfav_course"),
class MyFavCourseView(LoginRequiredMixin,View):
"""
我收藏的课程
"""
def get(self, request):
course_list = []
fav_courses = UserFavorite.objects.filter(user=request.user, fav_type=1)
for fav_course in fav_courses:
course_id = fav_course.fav_id
course = Course.objects.get(id=course_id)
course_list.append(course)
return render(request, 'usercenter-fav-course.html', {
"course_list":course_list,
})
我的消息页面
#我的消息
path('my_message/', MyMessageView.as_view(), name="my_message"),
class MyMessageView(LoginRequiredMixin, View):
'''我的消息'''
def get(self, request):
all_message = UserMessage.objects.filter(user= request.user.id)
try:
page = request.GET.get('page', 1)
except PageNotAnInteger:
page = 1
p = Paginator(all_message, 4,request=request)
messages = p.page(page)
return render(request, "usercenter-message.html", {
"messages":messages,
})
取消收藏
修改usercenter-bae.html
模板中的Ajax代码
修改HTML文件
注册时发生欢迎消息
# 写入欢迎注册消息
user_message = UserMessage()
user_message.user = user_profile.id
user_message.message = "欢迎注册!!"
user_message.save()
页面顶部小喇叭
所有页面都要读取一个共同的变量:未读消息的数量。我们需要向request中注入这个变量
所有页面都有request.user对象。所以我们在userprofile中自定义方法,
# 获取用户未读消息的数量
def unread_nums(self):
from operation.models import UserMessage
return UserMessage.objects.filter(user=self.id).count()
退出
# 退出功能url
path('logout/', LogoutView.as_view(), name="logout"),
class LogoutView(View):
def get(self, request):
# django自带的logout
logout(request)
# 重定向到首页,
return HttpResponseRedirect(reverse("index"))
点击数加1
课程 CourseInfoView
course.students += 1
course.save()
TeacherDetailView
teacher.click_nums += 1
teacher.save()
OrgHomeView
course_org.click_nums += 1
course_org.save()
收藏数
organization/views.py中的 AddFavView
if exist_records:
# 如果记录已经存在, 则表示用户取消收藏
exist_records.delete()
if int(type) == 1:
course = Course.objects.get(id=int(id))
course.fav_nums -= 1
if course.fav_nums < 0:
course.fav_nums = 0
course.save()
elif int(type) == 2:
org = CourseOrg.objects.get(id=int(id))
org.fav_nums -= 1
if org.fav_nums < 0:
org.fav_nums = 0
org.save()
elif int(type) == 3:
teacher = Teacher.objects.get(id=int(id))
teacher.fav_nums -= 1
if teacher.fav_nums < 0:
teacher.fav_nums = 0
teacher.save()
return HttpResponse('{"status":"success", "msg":"收藏"}', content_type='application/json')
else:
user_fav = UserFavorite()
# 过滤掉未取到fav_id type的默认情况
if int(type) > 0 and int(id) > 0:
user_fav.fav_id = int(id)
user_fav.fav_type = int(type)
user_fav.user = request.user
user_fav.save()
if int(type) == 1:
course = Course.objects.get(id=int(id))
course.fav_nums += 1
course.save()
elif int(type) == 2:
org = CourseOrg.objects.get(id=int(id))
org.fav_nums += 1
org.save()
elif int(type) == 3:
teacher = Teacher.objects.get(id=int(id))
teacher.fav_nums += 1
teacher.save()
return HttpResponse('{"status":"success", "msg":"已收藏"}', content_type='application/json')
修改消息已读
class MyMessageView(LoginRequiredMixin, View):
'''我的消息'''
def get(self, request):
all_message = UserMessage.objects.filter(user= request.user.id)
# 用户进入个人中心消息页面,清空未读消息记录
all_unread_messages = all_message.filter(has_read=False)
for unread_message in all_unread_messages:
unread_message.has_read = True
unread_message.save()
try:
page = request.GET.get('page', 1)
except PageNotAnInteger:
page = 1
p = Paginator(all_message, 4, request=request)
messages = p.page(page)
return render(request, "usercenter-message.html", {
"messages":messages,
})
个人中心左侧active状态