5
第5章 通过xadmin快速搭建后台管理系统
- 通过xadmin结合第4章设计的model快速的搭建一套完整的后台管理系统;本章首先介绍django admin的简单使用, 然后引出xadmin,在安装xadmin之后将model注册到xadmin中, 最后完成xadmin的全局配置
- 权限管理
- 样式开发
- 快速开发
- 后台开发
5-1
setting更改语言.
LANGUAGE_CODE = 'zh-hans'
#更改时区
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
#更改为False,否则保存UTC的时间
USE_TZ = False
数据库报错,先不管他
5-2
安装xadmin
报错.
去github下载替换readme.rst
压缩zip
pip install xadmin.zip
- setting设置.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'courses',
'operation',
'organization',
'xadmin',
'crispy_forms'
]
2.路由界面导入
MxOnline/urls.py
from django.conf.urls import url
from django.contrib import admin
import xadmin
urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
]
- 迁移 makemigrations , migrate
5-3
apps/users/adminx.py
# _*_ coding: utf-8 _*_
__author__ = 'lv'
__date__ = '2017/11/24 21:16'
import xadmin
from .models import EmailVerifyRecord, Banner, UserProfile
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']
xadmin.site.register(EmailVerifyRecord, EmailVerifyRecordAdmin)
xadmin.site.register(Banner, BannerAdmin)
6-1
- 配置MxOnline/urls
from django.conf.urls import url
from django.contrib import admin
from django.views.generic import TemplateView
import xadmin
urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
-
把js,image,css,存放的static目录下.
-
setting更改路径.index更改路径.
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static")
)
6-2
- 熟练打断点.
- crsf掌握
6-7 注册
*配置网页的静态文件
MxOnline/setting
微信截图_20171128122946.png
template/register.html
微信截图_20171128123008.png
-
验证码框架
微信截图_20171128123524.png -
验证码验证
class RegisterForm(forms.Form):
email = forms.EmailField(required=True)
password = forms.CharField(required=True, min_length=5)
captcha = CaptchaField(error_messages={"invalid":u"验证码错误"})
就是传入浏览器POST请求,表格验证,如果错误就返回错误信息.
6-9 发送邮件验证.
- 目的:用于发送注册,更改验证码
apps/utils/email_send.py
from random import Random
from django.core.mail import send_mail
from users.models import EmailVerifyRecord
from MxOnline.settings import EMAIL_FROM
def random_str(randomlength=8):
str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
length = len(chars) - 1
random = Random()
for i in range(randomlength):
str+=chars[random.randint(0, length)]
return str
def send_register_email(email, send_type="register"):
email_record = EmailVerifyRecord()
code = random_str(16)
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/active/{0}".format(code)
send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
if send_status:
pass
- MxOnline/setting
EMAIL_HOST = "smtp.sina.com"
EMAIL_PORT = 25
EMAIL_HOST_USER = "projectsedu@sina.com"
EMAIL_HOST_PASSWORD = "admin123"
EMAIL_USE_TLS= False
EMAIL_FROM = "projectsedu@sina.com"
6-10 测试发送邮件
- 测试就是在view界面调用了send_register_email(user_name, "register")
然后我用的QQ邮箱生效了.
6-11 判断用户是否注册了
忘记密码
ForgetPwdView
get 返回网页.
post 如果验证正确,发送邮件,否则提示失败.
7-1模板继承
- 父模板 {% block title %} dudududu {% endblock %}
- 子模板
{% 'base.html' %}
{% block title %} dadadada {% endblock %}
7-3 机构类别
上传文件地址.
setting配置media,还要配置url
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
model类lim
python2 def Unicode(self)
python3 def str(self):
return self.name
7-4
模板显示图片配置图片地址路径要设置setting地址
data-url="{{ MEDIA_URL }}{{ course_org.image }}
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.media',
],
},
},
]
还要在url里设置路径
url(r'^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}),
7-5 分页库
- 目标:给机构分页
- 安装分页库
pip install django-pure-pagination
- setting添加pure-pagination
- views中写分页
try:
page = request.GET.get('page', 1)
except PageNotAnInteger:
page = 1
p = Paginator(all_orgs, 5, request=request)
orgs = p.page(page)
- 写模板
<div class="pageturn">
<ul class="pagelist">
{% if all_orgs.has_previous %}
<li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}">上一页</a></li>
{% endif %}
{% for page in all_orgs.pages %}
{% if page %}
{% ifequal page all_orgs.number %}
<li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li>
{% else %}
<li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
{% endifequal %}
{% else %}
<li class="none"><a href="">...</a></li>
{% endif %}
{% endfor %}
{% if all_orgs.has_next %}
<li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}">下一页</a></li>
{% endif %}
</ul>
</div>
报错说传入参数不对,是因为我导错包了,应该是pure-pagination我导入django本身的分页了.
7-6
- 学习人数,可成熟排序
- 增加字段
students = models.IntegerField(default=0, verbose_name=u"学习人数")
course_nums = models.IntegerField(default=0, verbose_name=u"课程数")
7-7
ModelForm
Form会对表单先验证再保存到数据库.
class UserAskForm(forms.Form):
name = forms.CharField(max_length=20, verbose_name=u"姓名")
mobile = forms.CharField(max_length=11, verbose_name=u"手机")
course_name = forms.CharField(max_length=50, verbose_name=u"课程名")
ModelForm可以简写成下面的
class UserAskForm(forms.ModelForm):
class Meta:
model = UserAsk
fields = ['name', 'mobile', 'course_name']
7-9
开始撒欢听歌对代码编辑.因为都是流水账了,试试自己可以不可以.
就是urls--views--templates
机构主页
- urls
url(r'^home/(?P<org_id>\d+)/$', OrgHomeView.as_view(), name="org_home"),
- views
class OrgHomeView(View):
"""
机构首页
"""
def get(self, request, org_id):
# 网页选项卡
current_page = "home"
# 通过传入机构id查找对应的课程
course_org = CourseOrg.objects.get(id=int(org_id))
# 增加点击数
course_org.click_nums += 1
course_org.save()
has_fav = False
# if request.user.is_authenticated():
# if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2):
# has_fav = True
all_courses = course_org.course_set.all()[:3]
all_teachers = course_org.teacher_set.all()[:1]
return render(request, 'org-detail-homepage.html', {
'all_courses':all_courses,
'all_teachers': all_teachers,
'course_org':course_org,
'current_page':current_page,
'has_fav':has_fav
})
- templates这里我先编辑org_base.html和org-detail-homepage.html
退出,和用户,其他页面选项卡,还有收藏没有做在html链接更改成#
机构课程
- urls
url(r'^course/(?P<org_id>\d+)/$', OrgCourseView.as_view(), name="org_course"),
- views
class OrgCourseView(View):
"""
机构课程列表页
"""
def get(self, request, org_id):
current_page = "course"
course_org = CourseOrg.objects.get(id=int(org_id))
has_fav = False
# if request.user.is_authenticated():
# if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2):
# has_fav = True
all_courses = course_org.course_set.all()
return render(request, 'org-detail-course.html', {
'all_courses':all_courses,
'course_org':course_org,
'current_page':current_page,
'has_fav':has_fav
})
机构介绍
- urls
url(r'^course/(?P<org_id>\d+)/$', OrgCourseView.as_view(), name="org_course"),
- views
class OrgCourseView(View):
"""
机构课程列表页
"""
def get(self, request, org_id):
current_page = "course"
course_org = CourseOrg.objects.get(id=int(org_id))
has_fav = False
# if request.user.is_authenticated():
# if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2):
# has_fav = True
all_courses = course_org.course_set.all()
return render(request, 'org-detail-course.html', {
'all_courses':all_courses,
'course_org':course_org,
'current_page':current_page,
'has_fav':has_fav
})
网友评论