本文共 21775 字,大约阅读时间需要 72 分钟。
目录
1、直接从,网页链接中获取信息
前端代码:
{% if request.path|slice:'9' == '/org/list' %}class="active"{% endif %}代码解释: request.path 取得当前网页的路径(没有域名的路径 如http://127.0.0.1:8000/org/home/2/ request.path结果为 /org/home/2/ )slice:'9' == '/org/list' 相当于re正则表达式 ,取前几位然后进行对比{% if request.path == '/' %}class="active"{% endif %}>首页公开课 授课教师 授课机构
Django models 对数据库的操作
后台代码(对课程进行搜索)
course.CourseListView()
class CourseList(View): def get(self,request): all_courses = Course.objects.all().order_by("-add_time") hot_courses = Course.objects.all().order_by("-click_nums")[:3] #完成搜索功能 search_keywords = request.GET.get('keywords','') if search_keywords: all_courses = all_courses.filter(Q(name__icontains= search_keywords)|Q(desc__icontains=search_keywords)|Q(detail__icontains=search_keywords))#name__icontains contains前面的i表示不区分大小写 #课程排序 sort = request.GET.get('sort','') if sort: if sort == 'hot': all_courses = all_courses.order_by('-click_nums') elif sort == 'students': all_courses = all_courses.order_by('-student') try: page = int(request.GET.get('page', 1))#这里要做一下int转换,这里的request.GET.get('page', 1)中的page是Django在分页时自动生成的 except PageNotAnInteger: page = 1 paginator = Paginator(all_courses,6,request=request)#每页显示条数3 courses = paginator.page(page) if request.user.is_authenticated: username = request.user else: username = '未登录,请点击登陆' return render(request,'course-list.html',{ 'all_courses': courses, 'sort':sort, 'hot_courses':hot_courses, 'username':username, })
重点在这里,对于课程,老师,机构都是这样写
search_keywords = request.GET.get('keywords','') if search_keywords: all_courses = all_courses.filter(Q(name__icontains= search_keywords)|Q(desc__icontains=search_keywords)|Q(detail__icontains=search_keywords))#name__icontains contains前面的i表示不区分大小写
前端代码:
在base.html 页面添加监听代码
function search_click(){ var type = $('#jsSelectOption').attr('data-value'),//拿到前端数据类型 keywords = $('#search_keywords').val(), //keywords 这个字段会传到后台,在后台进行查询,他的功能是拿到搜索框中用户输入的内容 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}
在所有用户中心页面配置时,在views.py中都要就继承LoginRequiredMixin,以判断用户是否登陆
1、userinfo 页面配置
首先先将 user_base页面进行配置,然后在userinfo.html页面中继承base页面,最后将后台数据传到前端
前端代码 用户信息直接从request.user 传值
值得注意的是:value="{
{ request.user.mobile|default_if_none:'' }} 后面的default_if_not是对手机号进行判断,如果为空那么将不填充,否则会填充上Noneusers.views.py
class UploadImgView(LoginRequiredMixin,View): def post(self,request): image_form = UploadImgForm(request.POST,request.FILES)#image是文件类型,不是字段所以后面要加上request.FILES if image_form.is_valid(): ''' 当前端上传图片的时候,如果前端拿到图片,那么clrarned_data里面变回存放前端验证通过的数据 而且数据的字段名称与前端的标签的属性名称一致 ''' img = image_form.cleaned_data['image'] # request.user.image = img request.user.save()
class UploadImgView(LoginRequiredMixin,View):''' UploadImgForm(request.POST)是前端form传递到 后台的数据 request.FILES 是签单传递的数据类型为file,不再是字段了(默认是字段) instance=request.user ''' image_form = UploadImgForm(request.POST,request.FILES,instance=request.user) if image_form.is_valid(): image_form.save() return HttpResponse(json.dump('{"status":"success"}'),content_type='application/json') else: return HttpResponse(json.dump('{"status":"fail"}'), content_type='application/json')
后台:
class ResetPwdView(View): def post(self,request): modify_form = ModifyPwdForm(request.POST) if modify_form.is_valid(): pwd1 = request.POST.get('password1','') pwd2 = request.POST.get('password2','') if pwd1 != pwd2: return HttpResponse(json.dumps('{"status":"fail","msg":"两次密码不一致,请重新输入"}'),content_type='application/json') else: user = request.user user.password = make_password(pwd1) user.save() return HttpResponse(json.dumps('{"status":"success"}'), content_type='application/json') else: return HttpResponse(json.dumps(modify_form.errors),content_type='application/json')
path('reset_pwd/',ResetPwdView.as_view(),name = "reset_pwd"),
前端:
$(function(){ //个人资料修改密码 $('#jsUserResetPwd').on('click', function(){ Dml.fun.showDialog('#jsResetDialog', '#jsResetPwdTips'); }); $('#jsResetPwdBtn').click(function(){ $.ajax({ cache: false, type: "POST", dataType:'json', url:"/index/reset_pwd/", data:$('#jsResetPwdForm').serialize(), async: true, success: function(data) { if(data.password1){ Dml.fun.showValidateError($("#pwd"), data.password1); }else if(data.password2){ Dml.fun.showValidateError($("#repwd"), data.password2); }else if(data.status == "success"){ Dml.fun.showTipsDialog({ title:'提交成功', h2:'修改密码成功,请重新登录!', }); Dml.fun.winReload(); }else if(data.msg){ Dml.fun.showValidateError($("#pwd"), data.msg); Dml.fun.showValidateError($("#repwd"), data.msg); } } }); }); //个人资料头像 $('.js-img-up').uploadPreview({ Img: ".js-img-show", Width: 94, Height: 94 ,Callback:function(){ $('#jsAvatarForm').submit(); }}); $('.changeemai_btn').click(function(){ Dml.fun.showDialog('#jsChangeEmailDialog', '#jsChangePhoneTips' ,'jsChangeEmailTips'); }); $('#jsChangeEmailCodeBtn').on('click', function(){ sendCodeChangeEmail($(this)); }); $('#jsChangeEmailBtn').on('click', function(){ changeEmailSubmit($(this)); }); //input获得焦点样式 $('.perinform input[type=text]').focus(function(){ $(this).parent('li').addClass('focus'); }); $('.perinform input[type=text]').blur(function(){ $(this).parent('li').removeClass('focus'); }); laydate({ elem: '#birth_day', format: 'YYYY-MM-DD', max: laydate.now() }); verify( [ {id: '#nick_name', tips: Dml.Msg.epNickName, require: true} ] ); //保存个人资料 $('#jsEditUserBtn').on('click', function(){ var _self = $(this), $jsEditUserForm = $('#jsEditUserForm') verify = verifySubmit( [ {id: '#nick_name', tips: Dml.Msg.epNickName, require: true} ] ); if(!verify){ return; } $.ajax({ cache: false, type: 'post', dataType:'json', url:"/users/info/", data:$jsEditUserForm.serialize(), async: true, beforeSend:function(XMLHttpRequest){ _self.val("保存中..."); _self.attr('disabled',true); }, success: function(data) { if(data.nick_name){ _showValidateError($('#nick_name'), data.nick_name); }else if(data.birday){ _showValidateError($('#birth_day'), data.birday); }else if(data.address){ _showValidateError($('#address'), data.address); }else if(data.status == "failure"){ Dml.fun.showTipsDialog({ title: '保存失败', h2: data.msg }); }else if(data.status == "success"){ Dml.fun.showTipsDialog({ title: '保存成功', h2: '个人信息修改成功!' }); setTimeout(function(){window.location.href = window.location.href;},1500); } }, complete: function(XMLHttpRequest){ _self.val("保存"); _self.removeAttr("disabled"); } }); });});
未解决的问题,
当密码符合但不一致是,不能给提示
未验证旧密码
密码修改成功后转到登陆页面,但是不能自动刷新,要将当前个人信息页面刷新才可以进入登录页面
后台代码:
sittings.py: 主要是设置邮箱的相关信息,如密码,主发邮箱号
EMAIL_HOST = 'smtp.qq.com'EMAIL_POSRT = 25EMAIL_HOST_USER = "1194380923@qq.com"#邮箱名EMAIL_HOST_PASSWORD = "xpkdjgkhhwvbgjce"#密码,这里要换成授权码EMAIL_USE_TLS = FalseEMAIL_FROM = "1194380923@qq.com"#邮箱名
users.email_send.py
这是一个可供其他方法调用的发送邮箱的方法,不能和视屏一样放在utils里面,会出错(为什么我也不知道)
import randomfrom django.core.mail import send_mailfrom .models import EmailVerifyRecordfrom MXonline.settings import EMAIL_FROMdef send_register_email(email,send_type="register"):#参数含义:email将要发送的邮箱地址,type发送邮件的当下情 email_record = EmailVerifyRecord() code = random_str()#随机验证码 email_record.code = code email_record.email = email email_record.send_type = send_type email_record.save()#将邮箱验证的信息(邮箱号,验证码,验证类型)存入到数据库,为之后用户填写验证码后台做验证的时候使用 #定义邮件内容 email_title = "" email_body = "" if send_type == "register": email_title = "激活链接" email_body = "请点击下面的激活链接:http://127.0.0.1:8000/index/active/"+str(code) send_status = send_mail(email_title,email_body,EMAIL_FROM,[email]) if send_status: pass elif send_type == "forget": email_title = "密码重置链接" email_body = "请点击下面的密码重置链接:http://127.0.0.1:8000/index/reset/"+str(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: pass if send_type == "update": email_title = "重置邮箱激活验证码" email_body = "你的邮箱激活验证码为:{0}".format(code) send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) if send_status: passdef random_str(): number = random.randint(100000,999999) string = str(number) return string
users.views
class ResetEmailView(View): ''' 发送邮箱验证码 ''' def get(self,request): email = request.GET.get('email','') if UserProfile.objects.filter(email= email): return HttpResponse(json.dumps('{"email":"邮箱已存在"}'),content_type='application/json') send_register_email(email,'update') return HttpResponse(json.dumps('{"status":"success"}'),content_type='application/json')class EmailVerifyView(LoginRequiredMixin, View): def post(self, request): email = request.POST.get('email','') code = request.POST.get('code','') if EmailVerifyRecord.objects.filter(email = email,code=code, send_type = 'update'):#从数据库查询到当时发送邮件所保存的信息 user = request.user user.email = email user.save() return HttpResponse(json.dumps('{"status":"success"}'),content_type='application/json') else: return HttpResponse(json.dumps('{"email":"验证码出错"}'), content_type='application/json')
users.uels.py
path('reset_email/',ResetEmailView.as_view(),name = "reset_email"), path('send_emailcode/',EmailVerifyView.as_view(),name = "send_emailcode"),
前端代码
HTML代码
修改邮箱
请输入新的邮箱地址
js代码 ajax 看不懂,勉强能读
//修改个人中心邮箱验证码function sendCodeChangeEmail($btn){ var verify = verifyDialogSubmit( [ {id: '#jsChangeEmail', tips: Dml.Msg.epMail, errorTips: Dml.Msg.erMail, regName: 'email', require: true} ] ); if(!verify){ return; } $.ajax({ cache: false, type: "get", dataType:'json', url:"/index/reset_email/", data:$('#jsChangeEmailForm').serialize(), async: true, beforeSend:function(XMLHttpRequest){ $btn.val("发送中..."); $btn.attr('disabled',true); }, success: function(data){ if(data.email){ Dml.fun.showValidateError($('#jsChangeEmail'), data.email); }else if(data.status == 'success'){ Dml.fun.showErrorTips($('#jsChangeEmailTips'), "邮箱验证码已发送"); }else if(data.status == 'failure'){ Dml.fun.showValidateError($('#jsChangeEmail'), "邮箱验证码发送失败"); }else if(data.status == 'success'){ } }, complete: function(XMLHttpRequest){ $btn.val("获取验证码"); $btn.removeAttr("disabled"); } });}//个人资料邮箱修改function changeEmailSubmit($btn){var verify = verifyDialogSubmit( [ {id: '#jsChangeEmail', tips: Dml.Msg.epMail, errorTips: Dml.Msg.erMail, regName: 'email', require: true}, ] ); if(!verify){ return; } $.ajax({ cache: false, type: 'post', dataType:'json', url:"/index/send_emailcode/", data:$('#jsChangeEmailForm').serialize(), async: true, beforeSend:function(XMLHttpRequest){ $btn.val("发送中..."); $btn.attr('disabled',true); $("#jsChangeEmailTips").html("验证中...").show(500); }, success: function(data) { if(data.email){ Dml.fun.showValidateError($('#jsChangeEmail'), data.email); }else if(data.status == "success"){ Dml.fun.showErrorTips($('#jsChangePhoneTips'), "邮箱信息更新成功"); setTimeout(function(){location.reload();},1000); }else{ Dml.fun.showValidateError($('#jsChangeEmail'), "邮箱信息更新失败"); } }, complete: function(XMLHttpRequest){ $btn.val("完成"); $btn.removeAttr("disabled"); } });}
后台代码:
user.forms.py
class UserInfoForm(forms.ModelForm): class Meta: model = UserProfile fields = ['username','birthday','mobile','gender','address']
user.views.py
class ResetUserInfoView(LoginRequiredMixin,View): def post(self,request): ''' 因为UserInfoForm是继承ModelForm的form,所以user_info可以像model那样直接保存前端的数据到数据库 ''' user_info = UserInfoForm(request.POST,instance=request.user)#后面的request.user很重要,不知道为什么 if user_info.is_valid(): user_info.save() return HttpResponse(json.dumps('{"status":"success"}'),content_type='application/json') else: return HttpResponse(json.dumps(user_info.errors),content_type='application/json')
前端数据:
js 代码
$('#jsEditUserBtn').on('click', function(){ var _self = $(this), $jsEditUserForm = $('#jsEditUserForm') verify = verifySubmit( [ {id: '#nick_name', tips: Dml.Msg.epNickName, require: true} ] ); if(!verify){ return; }// debugger $.ajax({ cache: false, type: 'post', dataType:'json', url:"/index/info/", data:$jsEditUserForm.serialize(), async: true, beforeSend:function(XMLHttpRequest){ _self.val("保存中..."); _self.attr('disabled',true); }, success: function(data) { if(data.username){ _showValidateError($('#nick_name'), data.username); }else if(data.birthday){ _showValidateError($('#birth_day'), data.birthday); }else if(data.address){ _showValidateError($('#address'), data.address); }else if(data.status == "failure"){ Dml.fun.showTipsDialog({ title: '保存失败', h2: data.msg }); }else if(data.status == "success"){ Dml.fun.showTipsDialog({ title: '保存成功', h2: '个人信息修改成功!' }); setTimeout(function(){window.location.href = window.location.href;},1500); } }, complete: function(XMLHttpRequest){ _self.val("保存"); _self.removeAttr("disabled"); } }); });
后台代码:
class UserCourseView(LoginRequiredMixin,View): def get(self,request): usercourses = UserCourse.objects.filter(user = request.user) return render(request,'usercenter-mycourse.html',{ 'usercourses':usercourses, })
前端代码:
{% for course in usercourses %} {% endfor %}
后台代码:
、views.py
class UserFavCourseView(LoginRequiredMixin,View): def get(self,request): fav_courses = UserFavorate.objects.filter(fav_type = 1,user = request.user) msg = '' courses = [] if fav_courses: for fav in fav_courses: course = Course.objects.get(id = fav.fav_id) courses.append(course) return render(request, 'usercenter-fav-course.html', { 'courses': courses, 'msg':msg }) else: msg = '该同学没有收藏任何课程' return render(request,'usercenter-fav-course.html',{ 'msg':msg })class UserFavOrgView(LoginRequiredMixin,View): def get(self,request): fav_orgs = UserFavorate.objects.filter(fav_type=2, user=request.user) msg = '' orgs = [] if fav_orgs: for fav in fav_orgs: org = CourseOrg.objects.get(id=fav.fav_id) orgs.append(org) return render(request, 'usercenter-fav-org.html', { 'orgs': orgs, 'msg': msg }) else: msg = '该同学没有收藏任何课程机构' return render(request, 'usercenter-fav-org.html', { 'msg': msg })class UserFavTeacherView(LoginRequiredMixin,View): def get(self,request): fav_teachers = UserFavorate.objects.filter(fav_type=3, user=request.user) msg = '' teachers = [] if fav_teachers: for fav in fav_teachers: teacher = Teacher.objects.get(id=fav.fav_id) teachers.append(teacher) return render(request, 'usercenter-fav-teacher.html', { 'teachers': teachers, 'msg': msg }) else: msg = '该同学没有收藏任何老师' return render(request, 'usercenter-fav-teacher.html', { 'msg': msg })
urls.py
path('user_favcourse/',UserFavCourseView.as_view(),name = "user_favcourse"), path('user_favorg/',UserFavOrgView.as_view(),name = "user_favorg"), path('user_favteacher/',UserFavTeacherView.as_view(),name = "user_favteacher"),
前端:
和普通的配置一样,注意将所有连接改掉
前端接js代码
后台页面:
class UserProfile(AbstractUser):#扩展用户信息数据库 birthday = models.DateTimeField(verbose_name=u"生日", null=True, blank=True, default=None) nick_name = models.CharField(max_length=30, verbose_name=u"昵称", default=u"") #birthday = models.DateTimeField(verbose_name=u"生日",null=True,blank=True,default=u"") gender = models.CharField(choices=(("male",u"男"),("femal",u"女")),default=u"",max_length=6) address = models.CharField(max_length=100,default=u"") mobile = models.CharField(max_length=11,blank=True,null=True) image = models.ImageField(upload_to="image/%Y/%m",default=u"image/default.img",max_length=100)#用户头像和默认头像 class Meta: verbose_name = u"用户信息" verbose_name_plural = verbose_name def __str__(self):#admin 管理时返回的题目标题 return self.username def unread_message(self): ''' 获取当前用户未读的信息的条数 在当前方法内部 引入外部模块,防止循环引用 ''' from operation.models import UserMessage message = UserMessage.objects.filter(user = self.id,has_read = False) return message.count()
前端代码直接配置到页面
{ { request.user.unread_message }}
转载地址:http://jrnvb.baihongyu.com/