1.引入环境变量
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))
2.用户管理
from django.contrib.auth.models import AbstractUser
#继承AbstractUser 扩展系统自带的userinfo
class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=50, verbose_name=u"昵称", default="")
birday = models.DateField(verbose_name=u"生日", null=True, blank=True)
gender = models.CharField(max_length=6, choices=(("male",u"男"),("female","女")), default="female")
address = models.CharField(max_length=100, default=u"")
mobile = models.CharField(max_length=11, null=True, blank=True)
image = models.ImageField(upload_to="image/%Y/%m",default=u"image/default.png", max_length=100)
class Meta:
verbose_name = "用户信息"
verbose_name_plural = verbose_name
def __str__(self):
return self.username
def unread_nums(self):
#获取用户未读消息的数量
from operation.models import UserMessage
return UserMessage.objects.filter(user=self.id, has_read=False).count()
邮箱验证
class EmailVerifyRecord(models.Model):
code = models.CharField(max_length=20, verbose_name=u"验证码")
email = models.EmailField(max_length=50, verbose_name=u"邮箱")
send_type = models.CharField(verbose_name=u"验证码类型", choices=(("register",u"注册"),("forget",u"找回密码"), ("update_email",u"修改邮箱")), max_length=30)
send_time = models.DateTimeField(verbose_name=u"发送时间", default=datetime.now)
class Meta:
verbose_name = u"邮箱验证码"
verbose_name_plural = verbose_name
def __str__(self):
return '{0}({1})'.format(self.code, self.email)
轮播图
class Banner(models.Model):
title = models.CharField(max_length=100, verbose_name=u"标题")
image = models.ImageField(upload_to="banner/%Y/%m", verbose_name=u"轮播图", max_length=100)
url = models.URLField(max_length=200, verbose_name=u"访问地址")
index = models.IntegerField(default=100, verbose_name=u"顺序")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
verbose_name = u"轮播图"
verbose_name_plural = verbose_name
forms.py
#用来做验证
from django import forms
from captcha.fields import CaptchaField
from .models import UserProfile
class LoginForm(forms.Form):
username = forms.CharField(required=True)
password = forms.CharField(required=True, min_length=5)
class RegisterForm(forms.Form):
email = forms.EmailField(required=True)
password = forms.CharField(required=True, min_length=5)
captcha = CaptchaField(error_messages={"invalid":u"验证码错误"})
class ForgetForm(forms.Form):
email = forms.EmailField(required=True)
captcha = CaptchaField(error_messages={"invalid":u"验证码错误"})
class ModifyPwdForm(forms.Form):
password1 = forms.CharField(required=True, min_length=5)
password2 = forms.CharField(required=True, min_length=5)
class UploadImageForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['image']
class UserInfoForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['nick_name', 'gender', 'birday', 'address', 'mobile']
可以继承froms.Form , 也可以继承froms.ModelForm
apps.py
#用来设置apps的名字
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
verbose_name = u"用户信息"
admin.py
#生成admin后台页面
import xadmin
from xadmin import views
from xadmin.plugins.auth import UserAdmin
from xadmin.layout import Fieldset, Main, Side, Row
from django.utils.translation import ugettext as _
from .models import EmailVerifyRecord, Banner, UserProfile
class UserProfileAdmin(UserAdmin):
def get_form_layout(self):
if self.org_obj:
self.form_layout = (
Main(
Fieldset('',
'username',
css_class='unsort no_title'
),
Fieldset(_('Personal info'),
Row('first_name', 'last_name'),
'email'
),
Fieldset(_('Permissions'),
'groups', 'user_permissions'
),
Fieldset(_('Important dates'),
'last_login', 'date_joined'
),
),
Side(
Fieldset(_('Status'),
'is_active', 'is_staff', 'is_superuser',
),
)
)
return super(UserAdmin, self).get_form_layout()
class BaseSetting(object):
enable_themes = True
use_bootswatch = True
class GlobalSettings(object):
site_title = "慕学后台管理系统"
site_footer = "慕学在线网"
# menu_style = "accordion"
class EmailVerifyRecordAdmin(object):
list_display = ['code', 'email', 'send_type', 'send_time']
search_fields = ['code', 'email', 'send_type']
list_filter = ['code', 'email', 'send_type', 'send_time']
model_icon = 'fa fa-address-book-o'
class BannerAdmin(object):
list_display = ['title', 'image', 'url', 'index', 'add_time']
search_fields = ['title', 'image', 'url', 'index']
list_filter = ['title', 'image', 'url', 'index', 'add_time']
# from django.contrib.auth.models import User
# xadmin.site.unregister(User)
xadmin.site.register(EmailVerifyRecord, EmailVerifyRecordAdmin)
xadmin.site.register(Banner, BannerAdmin)
# xadmin.site.register(UserProfile, UserProfileAdmin)
xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GlobalSettings)
urls.py
#建立路由系统
from django.conf.urls import url, include
from .views import UserinfoView, UploadImageView, UpdatePwdView, SendEmailCodeView
from .views import UpdateEmailView, MyCourseView, MyFavOrgView, MyFavTeacherView, MyFavCourseView, MymessageView
urlpatterns = [
#用户信息
url(r'^info/$', UserinfoView.as_view(), name="user_info"),
#用户头像上传
url(r'^image/upload/$', UploadImageView.as_view(), name="image_upload"),
#用户个人中心修改密码
url(r'^update/pwd/$', UpdatePwdView.as_view(), name="update_pwd"),
#发送邮箱验证码
url(r'^sendemail_code/$', SendEmailCodeView.as_view(), name="sendemail_code"),
#修改邮箱
url(r'^update_email/$', UpdateEmailView.as_view(), name="update_email"),
#我的课程
url(r'^mycourse/$', MyCourseView.as_view(), name="mycourse"),
#我收藏的课程机构
url(r'^myfav/org/$', MyFavOrgView.as_view(), name="myfav_org"),
#我收藏的授课讲师
url(r'^myfav/teacher/$', MyFavTeacherView.as_view(), name="myfav_teacher"),
#我收藏的课程
url(r'^myfav/course/$', MyFavCourseView.as_view(), name="myfav_course"),
#我的消息
url(r'^mymessage/$', MymessageView.as_view(), name="mymessage"),
]
views.py
#功能的实现
# _*_ encoding:utf-8 _*_
import json
from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.views.generic.base import View
from django.contrib.auth.hashers import make_password
from django.http import HttpResponse, HttpResponseRedirect
from pure_pagination import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse
from .models import UserProfile, EmailVerifyRecord
from .forms import LoginForm, RegisterForm, ForgetForm, ModifyPwdForm, UploadImageForm
from .forms import UserInfoForm
from utils.email_send import send_register_email
from utils.mixin_utils import LoginRequiredMixin
from operation.models import UserCourse, UserFavorite, UserMessage
from organization.models import CourseOrg, Teacher
from courses.models import Course
from .models import Banner
class CustomBackend(ModelBackend):
def authenticate(self, username=None, password=None, **kwargs):
try:
user = UserProfile.objects.get(Q(username=username)|Q(email=username))
if user.check_password(password):
return user
except Exception as e:
return None
class AciveUserView(View):
def get(self, request, active_code):
all_records = EmailVerifyRecord.objects.filter(code=active_code)
if all_records:
for record in all_records:
email = record.email
user = UserProfile.objects.get(email=email)
user.is_active = True
user.save()
else:
return render(request, "active_fail.html")
return render(request, "login.html")
class RegisterView(View):
def get(self, request):
register_form = RegisterForm()
return render(request, "register.html", {'register_form':register_form})
def post(self, request):
register_form = RegisterForm(request.POST)
if register_form.is_valid():
user_name = request.POST.get("email", "")
if UserProfile.objects.filter(email=user_name):
return render(request, "register.html", {"register_form":register_form, "msg":"用户已经存在"})
pass_word = request.POST.get("password", "")
user_profile = UserProfile()
user_profile.username = user_name
user_profile.email = user_name
user_profile.is_active = False
user_profile.password = make_password(pass_word)
user_profile.save()
#写入欢迎注册消息
user_message = UserMessage()
user_message.user = user_profile.id
user_message.message = "欢迎注册慕学在线网"
user_message.save()
send_register_email(user_name, "register")
return render(request, "login.html")
else:
return render(request, "register.html", {"register_form":register_form})
class LogoutView(View):
"""
用户登出
"""
def get(self, request):
logout(request)
return HttpResponseRedirect(reverse("index"))
class LoginView(View):
def get(self, request):
return render(request, "login.html", {})
def post(self, request):
login_form = LoginForm(request.POST)
if login_form.is_valid():
user_name = request.POST.get("username", "")
pass_word = request.POST.get("password", "")
user = authenticate(username=user_name, password=pass_word)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "login.html", {"msg":"用户未激活!"})
else:
return render(request, "login.html", {"msg":"用户名或密码错误!"})
else:
return render(request, "login.html", {"login_form":login_form})
class ForgetPwdView(View):
def get(self, request):
forget_form = ForgetForm()
return render(request, "forgetpwd.html", {"forget_form":forget_form})
def post(self, request):
forget_form = ForgetForm(request.POST)
if forget_form.is_valid():
email = request.POST.get("email", "")
send_register_email(email, "forget")
return render(request, "send_success.html")
else:
return render(request, "forgetpwd.html", {"forget_form":forget_form})
class ResetView(View):
def get(self, request, active_code):
all_records = EmailVerifyRecord.objects.filter(code=active_code)
if all_records:
for record in all_records:
email = record.email
return render(request, "password_reset.html", {"email":email})
else:
return render(request, "active_fail.html")
return render(request, "login.html")
class ModifyPwdView(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", "")
email = request.POST.get("email", "")
if pwd1 != pwd2:
return render(request, "password_reset.html", {"email":email, "msg":"密码不一致"})
user = UserProfile.objects.get(email=email)
user.password = make_password(pwd2)
user.save()
return render(request, "login.html")
else:
email = request.POST.get("email", "")
return render(request, "password_reset.html", {"email":email, "modify_form":modify_form})
class UserinfoView(LoginRequiredMixin, View):
"""
用户个人信息
"""
def get(self, request):
return render(request, 'usercenter-info.html', {})
def post(self, request):
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')
class UploadImageView(LoginRequiredMixin, View):
"""
用户修改头像
"""
def post(self, request):
image_form = UploadImageForm(request.POST, request.FILES, instance=request.user)
if image_form.is_valid():
image_form.save()
return HttpResponse('{"status":"success"}', content_type='application/json')
else:
return HttpResponse('{"status":"fail"}', content_type='application/json')
class UpdatePwdView(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('{"status":"fail","msg":"密码不一致"}', content_type='application/json')
user = request.user
user.password = make_password(pwd2)
user.save()
return HttpResponse('{"status":"success"}', content_type='application/json')
else:
return HttpResponse(json.dumps(modify_form.errors), content_type='application/json')
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_email(email, "update_email")
return HttpResponse('{"status":"success"}', content_type='application/json')
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 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
})
class MyFavOrgView(LoginRequiredMixin, View):
"""
我收藏的课程机构
"""
def get(self, request):
org_list = []
fav_orgs = UserFavorite.objects.filter(user=request.user, fav_type=2)
for fav_org in fav_orgs:
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
})
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
})
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
teacher = Course.objects.get(id=course_id)
course_list.append(teacher)
return render(request, 'usercenter-fav-course.html', {
"course_list":course_list
})
class MymessageView(LoginRequiredMixin, View):
"""
我的消息
"""
def get(self, request):
all_messages = UserMessage.objects.filter(user=request.user.id)
#用户进入个人消息后清空未读消息的记录
all_unread_messages = UserMessage.objects.filter(user=request.user.id, 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_messages, 5, request=request)
messages = p.page(page)
return render(request, 'usercenter-message.html', {
"messages":messages
})
class IndexView(View):
#慕学在线网 首页
def get(self, request):
#取出轮播图
all_banners = Banner.objects.all().order_by('index')
courses = Course.objects.filter(is_banner=False)[:6]
banner_courses = Course.objects.filter(is_banner=True)[:3]
course_orgs = CourseOrg.objects.all()[:15]
return render(request, 'index.html', {
'all_banners':all_banners,
'courses':courses,
'banner_courses':banner_courses,
'course_orgs':course_orgs
})
def page_not_found(request):
#全局404处理函数
from django.shortcuts import render_to_response
response = render_to_response('404.html', {})
response.status_code = 404
return response
def page_error(request):
#全局500处理函数
from django.shortcuts import render_to_response
response = render_to_response('500.html', {})
response.status_code = 500
return response
前端页面的实现
404.html
<!DOCTYPE html>
<html>
{% load staticfiles %}
<head>
<meta charset="UTF-8">
<title>404</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/animate.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
</head>
<body class="bg404 errorpage">
<section>
<div class="wp">
<div class="cont">
<img src="{% static 'images/pic404.png' %}"/>
<br/><br/><br/><br/>
<p>wow~这个页面被外星人抢走了~</p>
<br/>
<span>Wow~ this page was the alien took ~</span>
</div>
</div>
</section>
</body>
</html>
500.html
<!DOCTYPE html>
<html>
{% load staticfiles %}
<head>
<meta charset="UTF-8">
<title>500</title>
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/animate.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
<script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
</head>
<body class="bg503 errorpage">
<section>
<div class="wp">
<div class="cont">
<div class="fl error_cut"><img src="{% static 'images/pic503.png' %}"/></div>
<div class="fr error_cut">
<img src="{% static 'images/word503.png' %}"/>
<br/><br/><br/><br/><br/><br/>
<p>服务器错误,请稍后重新刷新。</p>
</div>
</div>
</div>
</section>
</body>
</html>