社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
用到的包是virtualenv和vrtualenvwrapper-win
新建虚拟环境
mkvirtualenv mxonline
激活虚拟环境
workon mxonline
django-admin startproject MxOnline
python manage.py startapp user
pip install django==1.9
pip install mysqlclient #连接数据库
pip install pillow #图片的加载
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "mxonline",
'USER': "root",
'PASSWORD': "888888",
'HOST': "127.0.0.1",
}
}
数据迁移
python manage.py makemigrations
python manage.py migrate
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
AUTH_USER_MODEL = "user.UserProfile"
# _*_ encoding:utf-8 _*_
from django.db import models
from django.contrib.auth.models import AbstractUser #继承原有表user中的字段,新填个性化字段
# Create your models here.
class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=50, verbose_name=u"昵称", default=u"")
birthday = models.DateField(verbose_name=u"生日", null=True, blank=True)
gender = models.CharField(max_length=5, choices=(("male", u"男"), ("female", "女")), default=u"")
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 __unicode__(self):
return self.username
class EmailVerifiyRecord(models.Model):
code = models.CharField(max_length=20, verbose_name=u"验证码")
email = models.EmailField(max_length=50, verbose_name=u"邮箱")
send_type = models.CharField(choices=(("regiser", u"注册"), ("forget", u"找回密码")), max_length=10)
send_time = models.DateField(default=datetime.now)
class Meta:
verbose_name = u"邮箱验证码"
verbose_name_plural = verbose_name
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.DateField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
verbose_name = u"轮播图"
verbose_name_plural = verbose_name
class Course(models.Model):
name = models.CharField(max_length=50, verbose_name=u"课程名")
desc = models.CharField(max_length=300, verbose_name=u"课程描述")
detail = models.TextField(verbose_name=u"课程详情")
degree = models.CharField(choices=(("cj", "初级"), ("zj", "中级"), ("gj", "高级")), max_length=2)
learn_time = models.IntegerField(default=0, verbose_name=u"学习时长(分钟)")
student = models.IntegerField(default=0, verbose_name=u"学习人数")
fav_nums = models.IntegerField(default=0, verbose_name=u"收藏人数")
image = models.ImageField(upload_to="course/%Y/m", verbose_name=u"封面图", max_length=100)
click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
add_time = models.DateField(default=datetime.now,verbose_name=u"添加时间")
class Meta:
class Meta:
verbose_name = u"课程"
verbose_name_plural = verbose_name
class Lesson(models.Model):
course = models.ForeignKey(Course, verbose_name=u"课程")
name = models.CharField(max_length=100, verbose_name=u"章节名")
add_time = models.DateField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
class Meta:
verbose_name = u"章节"
verbose_name_plural = verbose_name
class Video(models.Model):
lesson = models.ForeignKey(Lesson, verbose_name=u"章节")
name = models.CharField(max_length=100, verbose_name=u"视频名")
add_time = models.DateField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
class Meta:
verbose_name = u"视频"
verbose_name_plural = verbose_name
class CourseResource(models.Model):
course = models.ForeignKey(Course, verbose_name=u"课程")
name = models.CharField(max_length=100, verbose_name=u"名称")
download = models.FileField(upload_to="course/%Y/%m", verbose_name=u"资源文件", max_length=100)
add_time = models.DateField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
class Meta:
verbose_name = u"课程资源"
verbose_name_plural = verbose_name
class CourseOrg(models.Model):
name = models.CharField(max_length=50, verbose_name=u"机构名称")
desc = models.TextField(verbose_name=u"机构描述")
click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
fav_nums = models.IntegerField(default=0, verbose_name=u"收藏数")
image = models.ImageField(upload_to="org/%Y/m", verbose_name=u"封面图", max_length=100)
address = models.CharField(max_length=150, verbose_name=u"机构地址")
city = models.ForeignKey(CityDict, verbose_name=u"所咋城市")
add_time = models.DateField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
class Meta:
verbose_name = u"课程机构"
verbose_name_plural = verbose_name
class Teacher(models.Model):
org = models.ForeignKey(CourseOrg, verbose_name=u"所属机构")
name = models.CharField(max_length=50, verbose_name=u"教师名")
work_years = models.IntegerField(default=0, verbose_name=u"工作年限")
work_company = models.CharField(max_length=50, verbose_name=u"就职公司")
work_position = models.CharField(max_length=50, verbose_name=u"公司职位")
points = models.CharField(max_length=50, verbose_name=u"教学特点")
click_nums = models.IntegerField(default=0, verbose_name=u"点击数")
fav_nums = models.IntegerField(default=0, verbose_name=u"收藏数")
add_time = models.DateField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
class Meta:
verbose_name = u"教师"
verbose_name_plural = verbose_name
class CityDict(models.Model):
name = models.CharField(max_length=20, verbose_name=u"城市")
desc = models.CharField(max_length=200, verbose_name=u"描述")
add_time = models.DateField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
class Meta:
verbose_name = u"城市"
verbose_name_plural = verbose_name
class UserAsk(models.Model):
name = models.CharField(max_length=20, verbose_name=u"姓名")
mobile = models.CharField(max_length=11, verbose_name=u"手机")
course_name = models.CharField(max_length=20, verbose_name=u"课程名")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
verbose_name = u"用户咨询"
verbose_name_plural = verbose_name
class CourseComments(models.Model):
#课程评论
user = models.ForeignKey(UserProfile,verbose_name=u"用户")
course = models.ForeignKey(Course,verbose_name=u"课程")
comments = models.CharField(max_length=200, verbose_name=u"评论")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
verbose_name = u"课程评论"
verbose_name_plural = verbose_name
class UserFavorite(models.Model):
user = models.ForeignKey(UserProfile, verbose_name=u"用户")
fav_id = models.IntegerField(default=0, verbose_name=u"数据id")
fav_type = models.IntegerField(choices=((1, "课程"), (2,"课程机构"), (3,"讲师")), default=1, verbose_name=u"收藏类型")
class Meta:
verbose_name = u"用户收藏"
verbose_name_plural = verbose_name
class UserMessage(models.Model):
user = models.IntegerField(default=0, verbose_name=u"接受用户")
message = models.CharField(max_length=500, verbose_name=u"消息内容")
has_read = models.BooleanField(default=False, verbose_name=u"是否已读")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
verbose_name = u"用户消息"
verbose_name_plural = verbose_name
class UserCourse(models.Model):
user = models.ForeignKey(UserProfile, verbose_name=u"用户")
course = models.ForeignKey(Course, verbose_name=u"课程")
add_time = models.DateTimeField(default=datetime.now, verbose_name=u"添加时间")
class Meta:
verbose_name = u"用户课程"
verbose_name_plural = verbose_name
import os
import sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
python manage.py createsuperuser
#root
#root280010
LANGUAGE_CODE = 'zh-hans' #中文
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False #本地时间
在admin.py下注册
from .models import UserProfile
class UserProfileAdmin(admin.ModelAdmin):
pass
admin.site.register(UserProfile, UserProfileAdmin)
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
(1)新建空白文件README.rst
压缩进 zip 中替换掉同名文件
下载后,从错误中可以看到,是文件README.rst
出现了 Unicode 解码错误,这个文件时没有什么用处的,可以新建一个同名的空白文件替换掉。
(2). 然后我们通过 cd 命令切换到该文件夹目录下,通过下面命令安装:
python setup.py install
(3)安装完成后,通过 pip list 可以看到 xadmin 以及相关依赖包都安装完成了。
(4)安装 import_export的包
但是你实际运行的时候又会发现,所以继续 安装成功以后,xadmin就算安装成功了。
pip install django-import-export
(1)在settings文件下
INSTALLED_APPS = (
'xadmin',
'crispy_forms',
'reversion',
)
(2)在url文件下
import xadmin
# url(r'^admin/', admin.site.urls),
url(r'^xadmin/', xadmin.site.urls),
数据库会更新出一些新的表
也可以将xadmin拷贝到项目中,修改源码,提供丰富的插件
在settings中设置
import os
import sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
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'))
# _*_ coding: utf-8 _*_
import xadmin
from .models import CityDict, CourseOrg, Teacher
class CityDictAdmin(object):
list_display = ['name', 'desc', 'add_time'] #显示列
search_fields = ['name', 'desc'] #搜索
list_filter = ['name', 'desc', 'add_time'] #过滤器
class CourseOrgAdmin(object):
list_display = [' name', 'desc', 'click_nums', 'fav_nums', 'image', 'address', 'city', 'add_time'] # 显示列
search_fields = [' name', 'desc', 'click_nums', 'fav_nums', 'image', 'address', 'city'] # 搜索
list_filter = [' name', 'desc', 'click_nums', 'fav_nums', 'image', 'address', 'city', 'add_time'] # 过滤器
class TeacherAdmin(object):
list_display = ['org', 'name', 'work_years', 'work_company', 'work_position', 'points', 'click_nums', 'fav_nums', 'add_time'] # 显示列
search_fields = ['org', 'name', 'work_years', 'work_company', 'work_position', 'points', 'click_nums', 'fav_nums'] # 搜索
list_filter = ['org', 'name', 'work_years', 'work_company', 'work_position', 'points', 'click_nums', 'fav_nums', 'add_time'] # 过滤器
xadmin.site.register(CityDict, CityDictAdmin)
xadmin.site.register(CourseOrg, CourseOrgAdmin)
xadmin.site.register(Teacher, TeacherAdmin)
(1)显示主题修改页面风格
from xadmin import views
class BaseSetting(object):
enable_themes = True
use_bootswatch = True
class GlobalSettings(object):
site_title = "鹏鹏教学后台管理系统"
site_footer = "鹏鹏教学网"
xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GlobalSettings)
(2)导航栏的设置以及更改apps为中文名
apps.py设置
# _*_ coding: utf-8 _*_
from django.apps import AppConfig
class OperationConfig(AppConfig):
name = 'operation'
verbose_name = u"用户操作"
__init__.py设置
default_app_config = "user.apps.UserConfig"
效果图
跳转页面login前没有/,将css,js,images导入到static,并配置static
from user.views import LoginView
urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
url('^$', TemplateView.as_view(template_name="index.html"), name="index"),
url('^login/$', LoginView.as_view(), name="login"),
]
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
("css", os.path.join(STATIC_ROOT, 'css')),
("images", os.path.join(STATIC_ROOT, 'images').replace('\', '/')),
("js", os.path.join(STATIC_ROOT, 'js')),
("img", os.path.join(STATIC_ROOT, 'img')),
from django.conf.urls import url
from django.contrib import admin
from django.views.generic import TemplateView
import xadmin
from user.views import LoginView
urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
url('^$', TemplateView.as_view(template_name="index.html"), name="index"),
url('^login/$', LoginView.as_view(), name="login"),
]
from django.contrib.auth import authenticate, login
from django.views.generic.base import View
#用户登陆模块
class LoginView(View):
def get(self, request):
return render(request, "login.html", {})
def post(self, request):
#提交到表单form里面做验证
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:
login(request, user)
return render(request, "index.html")
else:
return render(request, "login.html", {"msg": "用户名或密码错误!"})
else:
return render(request, "login.html", {"login_form": login_form})
settings.py配置
# Application definition
AUTHENTICATION_BACKENDS = (
'user.views.CustomBackend',
)
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q #并集
from .models import UserProfile
#使用邮箱也可以登陆
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
index.html设置
{% if request.user.is_authenticated %}
<div class="top">
<div class="wp">
<div class="fl"><p>服务电话:<b>18582854749</b></p></div>
<!--登录后跳转-->
<div class="personal">
<dl class="user fr">
<dd>鹏鹏<img class="down fr" src="/static/images/top_down.png"/></dd>
<dt><img width="20" height="20" src="/static/media/image/2016/12/default_big_14.png"/></dt>
</dl>
<div class="userdetail">
<dl>
<dt><img width="80" height="80" src="/static/media/image/2016/12/default_big_14.png"/></dt>
<dd>
<h2>管理员</h2>
<p>root@qq.com</p>
</dd>
</dl>
<div class="btn">
<a class="personcenter fl" href="usercenter-info.html">进入个人中心</a>
<a class="fr" href="/logout/">退出</a>
</div>
</div>
</div>
</div>
</div>
{% else %}
<div class="top">
<a style="color:white" class="fr registerbtn" href="register.html">注册</a>
<a style="color:white" class="fr loginbtn" href="/login/">登录</a>
{% endif %}
login.html 如果用户信息出错,则显示错误信息
<div class="error btns login-form-tips" id="jsLoginTips">{{ msg }}</div>
用于验证用户名和密码,减轻后台验证的负担
后台新建form.py
#表单,用来验证
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(required=True)
password = forms.CharField(required=True, min_length=5)
前端设置信息
#高亮
<div class="form-group marb20 {% if login_form.errors.username %}errorput{% endif %}">
#错误提示
<div class="error btns login-form-tips" id="jsLoginTips">{% for key, error in login_form.errors.items %}{{ key }}:{{ error }}{% endfor %}{{ msg }}</div>
#路径返回
<form id="email_register_form" method="post" action="{% url 'register' %}" autocomplete="off">
{% csrf_token %}
#信息回填
value="{{ register_form.email.value }}
效果图如下:
cookie在本地浏览器,sesson服务器
(1)配置
url.py
url('^register/$', RegisterView.as_view(), name="register"),
index.html
<div class="top">
<a style="color:white" class="fr registerbtn" href="{% url 'register' %}">注册</a>
<a style="color:white" class="fr loginbtn" href="{% url 'login' %}">登录</a>
register.html,使用这样的方式设置路径,便于以后路径的修改
<!DOCTYPE html>
<html>
{% load staticfiles %}
link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
#1.pip
pip install django-simple-captcha==0.4.6
2.Add captcha to the INSTALLED_APPS in your settings.py
3.Add an entry to your urls.py:
urlpatterns += [
url(r'^captcha/', include('captcha.urls')),
]
#生成数据库表
python manage.py makemigrations
python manage.py migrate
#用户注册
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", "")
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()
send_register_email(user_name, "register")
return render(request, "login.html")
else:
return render(request, "register.html", {"register_form": register_form})
url
url(r'^active/(?P<active_code>.*)/$', ActiveUserView.as_view(), name="user_active"),
settings,注意授权,密码是授权码
#配置邮箱验证
EMAIL_HOST = "smtp.163.com"
EMAIL_PORT = 25
EMAIL_HOST_USER = "wenpeng_111@163.com"
EMAIL_HOST_PASSWORD = "51dk648171lm" #授权码
EMAIL_USE_TLS = False
EMAIL_FROM = "wenpeng_111@163.com" #指明发件人
自动生成随机字符串
# _*_ coding: utf-8 _*_
from random import Random
from django.core.mail import send_mail
from user.models import EmailVerifiyRecord
from MxOnline.settings import EMAIL_FROM
def random_str(randomlength=8):
str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
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 = EmailVerifiyRecord()
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
view.py
#密码找回
class ForgetPwdView(View):
def get(self, request):
forget_form = ForgetForm(request.POST)
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 = EmailVerifiyRecord.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(pwd1)
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})
url.py
#密码找回
url(r'^forget/$', ForgetPwdView.as_view(), name="forget_pwd"),
url(r'^reset/(?P<active_code>.*)/$', ResetView.as_view(), name="reset_pwd"),
url(r'^modify_pwd/$', ModifyPwdView.as_view(), name="modify_pwd"),
password_reset.html
<div class="wp">
<div class="resetpassword" id="resetPwdForm">
<h1>修改密码</h1>
<p>已经通过验证,请设置新密码</p>
<form id="reset_password_form" action="{% url 'modify_pwd' %}" method="post">
<ul>
<li>
<span class="">新 密 码 :</span>
<input type="password" name="password1" id="pwd" placeholder="6-20位非中文字符">
<i></i>
</li>
<input type="hidden" name="email" value="{{ email }}">
<li>
<span class="">确定密码:</span>
<input type="password" name="password2" id="repwd" placeholder="6-20位非中文字符">
<i></i>
</li>
<li class="button">
<input type="button" value="提交" οnclick="reset_password_form_submit()">
</li>
</ul>
{% csrf_token %}
{% extends 'base.html' %}
{% block title %}课程机构列表 - 慕学在线网{% endblock %}
{% load staticfiles %}
{% block custom_bread %}
<section>
<div class="wp">
<ul class="crumbs">
<li><a href="index.html">首页1</a>></li>
<li>课程机构1</li>
</ul>
</div>
</section>
{% endblock %}
media用于存放用户上传的文件或者图片
(1)settings.py路径设置
设置 media 路径与目录
import os
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
settings 中配置模板的处理器
Templates[
'django.core.context_processors.media',
]
到这一步,仍然不能显示图片,在网页源代码中可以看到有图片的地址。但是仍然需要在 urls 中配置图片地址的路由,让 Django 知道到那个地方去取回图片。
(2)templates中图片地址
data-url="{{ MEDIA_URL }}{{ course_org.image }}
{% for course_org in all_orgs %}
<dl class="des difdes">
<a href="org-detail-homepage.html">
<img width="200" height="120" class="scrollLoading"
data-url="{{ MEDIA_URL }}{{ course_org.image }}"/>
{% endfor %}
(3)url.py配置一个处理静态文件的路由
# -*- coding:utf-8 -*-
from django.views.static import serve
from MxOnline.settings import MEDIA_ROOT
urlpatterns = [
# 处理 media 信息,用于图片获取
url(r'^media/(?P<path>.*)$', serve, {"document_root":MEDIA_ROOT}),]
pip install django-pure-pagination
(1)settings.py
INSTALLED_APPS = (
'pure_pagination',
)
(2)控制页数设定
PAGINATION_SETTINGS = {
'PAGE_RANGE_DISPLAYED': 10,
'MARGIN_PAGES_DISPLAYED': 2,
'SHOW_FIRST_PAGE_WHEN_INVALID': True,
}
(3)view.py设定
# _*_ encoding:utf-8 _*_
from django.shortcuts import render
from django.views.generic import View
from pure_pagination import Paginator, EmptyPage, PageNotAnInteger #分页
from .models import CourseOrg, CityDict,Teacher
class OrgView(View):
#课程机构列表功能
def get(self, request):
#课程机构
all_orgs = CourseOrg.objects.all()
org_nums = all_orgs.count()
#城市
all_cities = CityDict.objects.all()
#对课程机构进行分页
try:
page = request.GET.get('page', 1)
except PageNotAnInteger:
page = 1
p = Paginator(all_orgs, 4, request=request)
orgs = p.page(page)
return render(request, "org-list.html", {
"all_orgs": orgs,
"all_cities": all_cities,
"org_nums": org_nums,
"city_id": city_id,
"category": category,
"hot_orgs": hot_orgs,
"sort": sort
})
(4)templates设定org-list.html(分页的设定属于约定俗成的东西)
<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>
(1)所属地区筛选
(2)机构类别筛选
view.py
#取出筛选城市
city_id = request.GET.get('city', "")
if city_id:
all_orgs = all_orgs.filter(city_id=int(city_id))
#机构类别筛选
category = request.GET.get('ct', '')
if category:
all_orgs = all_orgs.filter(category=category)
#每一列的总数
org_nums = all_orgs.count()
org-list.html
<h2>机构类别</h2>
<div class="cont">
<a href="?city={{ city_id }}"><span class="{% ifequal category '' %}active2{% endifequal %}">全部</span></a>
<a href="?ct=pxjg&city={{ city_id }}"><span class="{% ifequal category 'pxjg' %}active2{% endifequal %}">培训机构</span></a>
<a href="?ct=gx&city={{ city_id }}"><span class="{% ifequal category 'gx' %}active2{% endifequal %}">高校</span></a>
<a href="?ct=gr&city={{ city_id }}"><span class="{% ifequal category 'gr' %}active2{% endifequal %}">个人</span></a>
</div>
<h2>所在地区</h2>
<div class="more">更多</div>
<div class="cont">
<a href="?ct={{ category }}"><span class="{% ifequal city_id '' %}active2{% endifequal %}">全部</span></a>
{% for city in all_cities %}
<a href="?city={{ city.id }}&ct={{ category }}"><span class="{% ifequal city_id city.id|stringformat:'i' %}active2{% endifequal %}">{{ city.name }}</span></a>
{% endfor %}
</div>
(1)授课机构排名
(2)所属列表排序(学习人数和课程数)
views.py
#课程机构排名
hot_orgs = all_orgs.order_by("click_nums")[:5]
#所属列表排序
sort = request.GET.get('sort', "")
if sort:
if sort == "students":
all_orgs = all_orgs.order_by("-students")
elif sort == "courses":
all_orgs = all_orgs.order_by("-course_nums")
org-list.html 各种情况下的排序杂糅到一块,一定相互关联!active高亮
#授课机构排序
<div class="right companyrank layout">
<div class="head">授课机构排名</div>
{% for current_org in hot_orgs %}
<dl class="des">
<dt class="num fl">{{ forloop.counter }}</dt>
<dd>
<a href="/company/2/"><h1>{{ current_org.name }}</h1></a>
<p>{{ current_org.address }}</p>
</dd>
</dl>
{% endfor %}
</div>
#所属列的排序
<div class="head">
<ul class="tab_header">
<li class="{% if sort == '' %}active{% endif %}"><a href="?&ct{{ category }}&city{{ city_id }}">全部</a> </li>
<li class="{% if sort == 'students' %}active{% endif %}"><a href="?sort=students&ct{{ category }}&city{{ city_id }}">学习人数 ↓</a></li>
<li class="{% if sort == 'courses' %}active{% endif %}"><a href="?sort=courses&ct{{ category }}&city{{ city_id }}">课程数 ↓</a></li>
</ul>
</div>
在总url里面设置路由分发
#课程机构url配置
url(r'^org/', include('organization.urls', namespace="org")),
在organization里新建子路由url
from django.conf.urls import url, include
from .views import OrgView, AddUserAskView
urlpatterns = [
# 课程机构列表页
url(r'^list/$', OrgView.as_view(), name="org_list"),
url(r'^add_ask', AddUserAskView.as_view(), name="add_ask")
]
view.py
使用HttpResponse返回json数据
from django.http import HttpResponse
from .forms import UserAskForm
#表单的提交
class AddUserAskView(View):
#用户添加咨询
def post(self, request):
userask_form = UserAskForm(request.POST)
if userask_form.is_valid():
user_ask = userask_form.save(commit=True)
#返回异步操作ajax/json
return HttpResponse("{'status':'success'}", content_type='application/json')
else:
return HttpResponse("{'status':'fail','msg':'添加出错'}", content_type='application/json')
在organization里面新建forms.py,使用ModelForm验证。
# _*_ coding: utf-8 _*_
import re
from django import forms
from operation.models import UserAsk
class UserAskForm(forms.ModelForm):
class Meta:
model = UserAsk
fields = ['name', 'mobile', 'course_name']
def clean_mobile(self):
#验证手机号码是否合法
mobile = self.cleaned_data['mobile']
REGEX_MOBILE = "^1[358]d{9}$|^147d{8}$|^176d{8}$"
p = re.compile(REGEX_MOBILE)
if p.match(mobile):
return mobile
else:
raise forms.ValidationError(u"手机号码非法", code="mobile_invalid")
重点在templates里面通过js的框架jquery配置ajax,实现数据的异步传输
{% block custom_js %}
<script>
$(function(){
$('#jsStayBtn').on('click', function(){
$.ajax({
cache: false,
type: "POST",
url:"{% url 'org:add_ask' %}",
data:$('#jsStayForm').serialize(),
async: true,
success: function(data) {
console.log(data)
alert(data)
if(data.status == 'success'){
$('#jsStayForm')[0].reset();
alert("提交成功")
}else if(data.status == 'fail'){
$('#jsCompanyTips').html(data.msg)
}
},
});
});
})
</script>
{% endblock %}
数据库结果
url.py
from django.conf.urls import url, include
from .views import OrgView, AddUserAskView, OrgHomeView, OrgCourseView, OrgDescView, OrgTeacherView
urlpatterns = [
# 课程机构列表页
url(r'^list/$', OrgView.as_view(), name="org_list"),
url(r'^add_ask', AddUserAskView.as_view(), name="add_ask"),
url(r'^home/(?P<org_id>d+)/$', OrgHomeView.as_view(), name="org_home"),
url(r'^course/(?P<org_id>d+)/$', OrgCourseView.as_view(), name="org_course"),
url(r'^desc/(?P<org_id>d+)/$', OrgDescView.as_view(), name="org_desc"),
url(r'^teacher/(?P<org_id>d+)/$', OrgTeacherView.as_view(), name="org_teacher"),
]
view.py
#机构详情页
class OrgHomeView(View):
#机构首页
def get(self, request, org_id):
current_page = "home"
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()
all_teachers = course_org.teacher_set.all()
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
})
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
})
class OrgDescView(View):
# 机构介绍页
def get(self, request, org_id):
current_page = "desc"
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-desc.html', {
'all_courses': all_courses,
'course_org': course_org,
'current_page': current_page,
'has_fav': has_fav
})
class OrgTeacherView(View):
#机构教师页
def get(self, request, org_id):
current_page = "teacher"
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_teachers = course_org.teacher_set.all()
return render(request, 'org-detail-teachers.html', {
'all_teachers': all_teachers,
'course_org': course_org,
'current_page': current_page,
'has_fav': has_fav
})
templates 新建org-list.html作为机构母页
新建母页org_base.html
<!DOCTYPE html>
<html>
{% load staticfiles %}
<head>
<meta charset="UTF-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" >
<title>{% block title %}机构首页-慕学网{% endblock %}</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' %}">
<link rel="stylesheet" type="text/css" href="{% static 'js/plugins/queryCity/css/cityLayout.css' %}">
{% block custom_css %}{% endblock %}
<script src="{% static 'js/jquery.min.js' %}" type="text/javascript"></script>
<script src="{% static 'js/jquery-migrate-1.2.1.min.js' %}" type="text/javascript"></script>
{% block custom_js %}{% endblock %}
</head>
<body>
<section class="headerwrap headerwrap2">
<header>
<div class="header2 header">
{% if request.user.is_authenticated %}
<div class="top">
<div class="wp">
<div class="fl"><p>服务电话:<b>18582854749</b></p></div>
<!--登录后跳转-->
<div class="personal">
<dl class="user fr">
<dd>鹏鹏<img class="down fr" src="/static/images/top_down.png"/></dd>
<dt><img width="20" height="20" src="/static/media/image/2016/12/default_big_14.png"/></dt>
</dl>
<div class="userdetail">
<dl>
<dt><img width="80" height="80" src="/static/media/image/2016/12/default_big_14.png"/></dt>
<dd>
<h2>管理员</h2>
<p>root@qq.com</p>
</dd>
</dl>
<div class="btn">
<a class="personcenter fl" href="usercenter-info.html">进入个人中心</a>
<a class="fr" href="/logout/">退出</a>
</div>
</div>
</div>
</div>
</div>
{% else %}
<div class="top">
<a style="color:white" class="fr registerbtn" href="{% url 'register' %}">注册</a>
<a style="color:white" class="fr loginbtn" href="{% url 'login' %}">登录</a>
{% endif %}
<div class="middle companyheader">
<div class="wp">
<img class="fl" style="width: 112px;height: 103px" src="{{ MEDIA_URL }}{{course_org.image}}"/>
<div class="head fl">
<h1>
慕课网
<img src="{% static 'images/authentication.png' %}"/>
<img src="{% static 'images/gold.png' %}"/>
</h1>
<p class="fl">
<span class="fl" style="margin-top:8px;color:#848484;">推荐指数: </span>
<span class="precision company-credit" data-star-scope="5.0"></span>
<span class="key">5.0</span>
</p>
</div>
<div class="btn fr collectionbtn notlogin
"data-favid="22" data-fav-type="1">
{% if has_fav %}已收藏{% else %}收藏{% endif %}
</div>
</div>
</div>
</div>
</header>
</section>
<section>
<div class="wp">
<ul class="crumbs">
<li><a href="index.html">首页</a>></li>
<li><a href="{% url 'org:org_list' %}">课程机构</a>></li>
<li>{% block page_path %}机构首页{% endblock %}</li>
</ul>
</div>
</section>
<section>
<div class="wp list personal_list comp">
<div class="left">
<ul>
<li class="{% ifequal current_page 'home' %}active2{% endifequal %}"><a href="{% url 'org:org_home' course_org.id %}">机构首页</a></li>
<li class="{% ifequal current_page 'course' %}active2{% endifequal %}"><a href="{% url 'org:org_course' course_org.id %}">机构课程</a></li>
<li class="{% ifequal current_page 'desc' %}active2{% endifequal %}"><a href="{% url 'org:org_desc' course_org.id %}">机构介绍</a></li>
<li class="{% ifequal current_page 'teacher' %}active2{% endifequal %}"><a href="{% url 'org:org_teacher' course_org.id %}">机构讲师</a></li>
</ul>
</div>
{% block right_form %}
{% endblock %}
</section>
<!--sidebar start-->
<section>
<ul class="sidebar">
<li class="qq">
<a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=2023525077&site=qq&menu=yes"></a>
</li>
<li class="totop"></li>
</ul>
</section>
<!--sidebar end-->
<!--header start-->
</div>
<!--弹出省省市-->
<script src="{% static 'js/selectUi.js' %}" type="text/javascript"></script>
<script type="text/javascript" src="{% static 'js/plugins/laydate/laydate.js' %}"></script>
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
<script src="{% static 'js/plugins/queryCity/js/public.js' %}" type="text/javascript"></script>
<script type="text/javascript" src="{% static 'js/plugins/jquery.raty.js' %}"></script>
<script type="text/javascript">
<!--收藏分享-->
function add_fav(current_elem, fav_id, fav_type){
$.ajax({
cache: false,
type: "POST",
url:'{% url "org:add_fav" %}',
data:{'fav_id':fav_id, 'fav_type':fav_type},
async: true,
beforeSend:function(xhr, settings){
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
},
success: function(data) {
if(data.status == 'fail'){
if(data.msg == '用户未登录'){
window.location.href="/login/";
}else{
current_elem.text(data.msg)
}
}else if(data.status == 'success'){
current_elem.text(data.msg)
}
},
});
}
$('.collectionbtn').on('click', function(){
add_fav($(this), {{ course_org.id }}, 2);
});
$(function(){
var $precision = $('.precision'),
score = $precision.attr('data-star-scope'),
option = {
half : true,
path : '{% static 'images/' %}',
precision : true,
size : 24,
starOff : 'g_star.png',
starOn : 'r_star.png',
starHalf : 'h_star.png',
hints : ['极差', '差', '一般', '好评', '非常满意'],
noRatedMsg : '暂时还未获得评价!',
readOnly : true,
score : score
};
$precision.raty(option);
$('.jsFavBtn').on('click', function(){
var type = $(this).attr('data-fav-type');
if(type == '1'){
favPraise($(this), 'fav' ,1 , '收藏');
}else if(type == '3'){
favPraise($(this), 'fav' ,3 );
}else if(type == '11'){
favPraise($(this), 'pra', 1);
}else if(type == '4'){
favPraise($(this), 'fav' ,4 );
}
});
})
</script>
<script type="text/javascript">
$(function() {
$('.recordbtn1').click(function(){
$('.recordbox1').show();
});
$('.recordbtn2').click(function(){
$('.recordbox2').show();
});
$('.imgslide').unslider({
speed: 500, // The speed to animate each slide (in milliseconds)
delay: 3000, // The delay between slide animations (in milliseconds)
complete: function() {}, // A function that gets called after every slide animation
keys: true, // Enable keyboard (left, right) arrow shortcuts
dots: true, // Display dot navigation
fluid: false // Support responsive design. May break non-responsive designs
});
var unslider = $('.imgslide').unslider();
$('.unslider-arrow').click(function() {
var fn = this.className.split(' ')[1];
unslider.data('unslider')[fn]();
});
});
</script>
</body>
</html>
(1)机构首页org-detail-homepage.html
{% extends 'org_base.html' %}
{% block title %}机构首页{% endblock %}
{% block page_path %}机构首页{% endblock %}
{% block right_form %}
<div class="right companycenter layout grouping" >
<div class="head">
<h1>全部课程</h1>
<a class="green fr more" href="org-detail-course.html">查看更多 > </a>
</div>
<div class="brief group_list">
{% for course in all_courses %}
<div class="module1_5 box">
<a href="course-detail.html"><img width="214" src="{{ MEDIA_URL }}{{ course.image }}"/></a>
<div class="des">
<a href="course-detail.html"><h2>{{ course.name }}</h2></a>
<span class="fl">课时:<i class="key">{{ course.learn_time }}</i></span>
<span class="fr">参加人数:{{ course.students }}</span>
</div>
<div class="bottom">
<span class="fl">{{ course.course_org.name }}</span>
<span class="star fr notlogin
" data-favid="13" data-fav-type="4">
{{ course.fav_nums }}
</span>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="right companycenter layout" >
<div class="head">
<h1>机构教师</h1>
<a class="green fr more" href="org-detail-teachers.html">查看更多 > </a>
</div>
{% for teacher in all_teachers %}
<div class="diarys">
<div class="module5 share company-diary-box" style="padding:10px 0;">
<div class="left">
<img class="pic" src="{{ MEDIA_URL }}{{ teacher.image }}"/>
<p>昵称:{{ teacher.name }}</p>
</div>
<div class="right">
<div class="top">
<div class="fl">
<a href=""><h1>java开发教程</h1></a>
<span>发表于:2015-10-12</span>
</div>
</div>
<div class="middle" style="border-bottom:0;">课程介绍</div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="right companycenter layout" >
<div class="head">
<h1>机构介绍</h1>
<a class="green fr more" href="org-detail-desc.html">查看更多 > </a>
</div>
<div class="cont"> {{ course_org.desc }}<
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!