moocOnline项目笔记

安装mysql驱动

pip install mysql-python

模型分层

opreation是下面几个模型的操作层
这里写图片描述

将多个app放入一个路径

  • 新建apps文件夹,将各app拉入,注意不要勾选下面两项
    这里写图片描述
  • 由于路径问题,operation会进行报错,如下图:
    这里写图片描述
  • 右键apps设置为资源路径,取消IDE报错。
    这里写图片描述
  • 在setting里面设置取消命令行运行报错
#将apps引入到资源路径中
sys.path.insert(0,os.path.join(BASE_DIR,'apps'))

django 后台汉化&时区调整

LANGUAGE_CODE = 'zh-hans'#后台汉化

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False#设置为False即采用本地时间非国际时间

错误解决1

  • 提示setting neither ….
通过转到venv / bin / activate并添加行来自动执行该过程: set DJANGO_SETTINGS_MODULE=mysite.settings到代码的底部。

错误解决2

Exception Value:    

(1452, 'Cannot add or update a child row: a foreign key constraint fails (`mooconline`.`django_admin_log`, CONSTRAINT `django_admin_log_user_id_52fdd58701c5f563_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`))')

修改,增加

    'default': {
...
        'OPTIONS': {
            "init_command": "SET foreign_key_checks = 0;",
        },
    },
  • 有时候错误莫名其妙,多谷歌,多试试,最好弄明白原理,但也不必浪费太多时间,还没到那阶段。

xadmin 后台

  • 安装
#先进入虚拟后台
(py2.7djangoj1.9) bogon:moocOnline eric$ pip install xadmin
  • 在settings中注册xadmin和crispy-forms依赖包
    'xadmin',
    'crispy_forms',#注意换成下滑线
  • 变更后台管理路径
import xadmin

urlpatterns = [
    url(r'^xadmin/', include(xadmin.site.urls)),
]
  • 注释掉admin.py 中的admin后台管理
  • 同步xadmin的表
python manage.py makemigrations
python manage.py migrate
  • 注册model
    在model下创建adminx.py文件,用来注册model
    这里写图片描述

通过源码安装

  • 上github下载源码,解压将xadmin文件夹放到项目中存放第三方源码的路径extra_apps下,并将extra_apps包mark成资源包。
  • 在settings里面设置
sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))

错误解决3

AppRegistryNotReady: Models aren't loaded yet

将manage.py 改成下面,再以具体是缺什么模块装什么模块。

import django
import os
import sys
from django.core.wsgi import get_wsgi_application

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "moocOnline.settings")
    django.setup()
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)
    application = get_wsgi_application()

错误解决4

(1146, "Table 'mooconline.xadmin_log' doesn't exist")
  • 这是因为使用源码安装xadmin后新的包有自己表需要创建,所以在同步一次数据库即可。

格式化输出

'{0}---{1}'.format(self.code,self.email)

定制显示列

  • 在管理器中设置
class EmailVerifyRecordAdmin(object):#注意这个继承
    list_display = ['code','email','send_type','send_time']

这里写图片描述

增加搜索功能

class EmailVerifyRecordAdmin(object):#注意这个继承
    list_display = ['code','email','send_type','send_time']
    search_fields = ['code','email','send_type']

这里写图片描述

增加过滤功能

list_filterv=  ['code','email','send_type','send_time']

这里写图片描述

错误解决5

  • 上传图片报错
is located outside of the base path component
  • 路径前多了个斜杠
upload_to='image/%Y/%m'

关于路径前的斜杠

(无)表示当前目录
(/)表示该目录为根目录的一个子目录
(./)表示此文件当前所在环境
(../)表示此文件所在环境的上一层环境

xadmin主题

class BaseSetting(object):
    enable_themes = True# 开启主题
    use_bootswatch = True

class GlobalSettings(object):
    site_title = '智创无限管理后台'
    site_footer = '智创无限有限责任公司'
    menu_style = 'accordion'#菜单折叠
  • 在apps.py中修改app的中文名
    这里写图片描述
    在app里添加apps.py
#coding:utf8
__author__ = 'eric'
__date__ = '2017/8/23 21:27'
from django.apps import AppConfig
class OperationConfig(AppConfig):
    name = 'courses'
    verbose_name = '课程'

在app的init.py里面增加下面代码

default_app_config = 'courses.apps.OperationConfig'

使用template来配置路径

from django.views.generic import TemplateView

urlpatterns = [
url(r'^$',TemplateView.as_view(template_name='index.html'),name='index'),
]

静态文件及模板路径

  • 模板路径配置,settings中
TEMPLATES = [
    {
    ...
        'DIRS': [os.path.join(BASE_DIR,'templates')],
    ...
]
  • 静态文件路径配置
STATIC_URL = '/static/'
STATICFILES_DIRS =(os.path.join(BASE_DIR, 'static'),)

注意要将静态文件中的相对路径改成static路径

403访问禁止

Django 为了防止csrf攻击,要求form表单提交要有token 验证,所以要在form后面加如下代码

     {% csrf_token %}
</form>

解决邮箱验证

  • 因为Django自带验证是基于用户名称的没有通过邮箱验证功能,所以我们需要重写auth验证类来达到邮箱验证功能
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

需要在setting中注册重写的类

#在这里注册重写的类
AUTHENTICATION_BACKENDS =(
    'users.views.CustomBackend',
)

基于类的登录判断优化

  • 之前是在views.py中创建登录验证函数,如下:
def userlogin(request):
    if request.method == 'POST':
        user_name = request.POST.get('username', '')
        pass_word = request.POST.get('password', '')
        # 通过authemticate方法验证用户提交的数据是否正确
        user = authenticate(username=user_name, password=pass_word)
        if user is not None:
            login(request, user)
            return render(request, 'index.html',locals())
        else:
            return render(request, 'login.html', {'msg':'用户名或密码错误'})
    elif request.method == 'GET':
        return render(request, 'login.html', {})
  • 比较麻烦,现进行基于类的继承方式来进行优化如下:
from django.views.generic.base import View
class LoginView(View):
    def get(self,request):
        return render(request, 'login.html', {})
    def post(self,request):
        user_name = request.POST.get('username', '')
        pass_word = request.POST.get('password', '')
        # 通过authemticate方法验证用户提交的数据是否正确
        user = authenticate(username=user_name, password=pass_word)
        if user is not None:
            login(request, user)
            return render(request, 'index.html', locals())
        else:
            return render(request, 'login.html', {'msg': '用户名或密码错误'})

在urls.py中调用如下:

url(r'^login/$',LoginView.as_view(),name='login'),

用django的form验证登录

  • 有时候提交的数据需要进行简单的验证,django 的form提供了该功能
    创建forms.py文件
# coding:utf8
from django import forms
class LoginForm(forms.Form):
    # 这里面的字段必须和前端form表单里面的字段一致,否则起不到验证效果
    username = forms.CharField(required=True)#必填
    password = forms.CharField(min_length=3)#最小长度为3

在views.py进行应用

#基于类的书写
from django.views.generic.base import View
class LoginView(View):
    def get(self,request):
        return render(request, 'login.html', {})
    def post(self,request):
        # 实例化一个form验证
        loginform = LoginForm(request.POST)  # 这里需要一个字典参数,request.POST刚好返回一个字典
        if loginform.is_valid():  # 判断是否合法
            user_name = request.POST.get('username', '')
            pass_word = request.POST.get('password', '')
            # 通过authemticate方法验证用户提交的数据是否正确
            user = authenticate(username=user_name, password=pass_word)
            if user is not None:
                login(request, user)
                return render(request, 'index.html', locals())
            else:
                return render(request, 'login.html', {'msg': '用户名或密码错误!'})
        else:
            return render(request, 'login.html', {'loginform': loginform })  # 如果输入格式不对,返回提示信息。

login.html

                <form action="/login/" method="post" autocomplete="off">
                    <input type='hidden' name='csrfmiddlewaretoken' value='mymQDzHWl2REXIfPMg2mJaLqDfaS1sD5'/>
                    <!--- 如果出现usermane的错误的提示-->
                    <div class="form-group marb20 {% if loginform.errors.username %} errorput {% endif %}">
                        <label>用&nbsp;户&nbsp;名</label>
                        <input name="username" id="account_l" type="text" placeholder="手机号/邮箱"/>
                    </div>
                {% if loginform.errors.username %}
                    <div class="error btns login-form-tips" id="jsLoginTips">{{ loginform.errors.username }}</div>
                {% endif %}
                    <div class="form-group marb8 {% if loginform.errors.password %} errorput {% endif %}">
                        <label>密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码</label>
                        <input name="password" id="password_l" type="password" placeholder="请输入您的密码"/>
                    </div>
                {% if loginform.errors.password %}
                    <div class="error btns login-form-tips" id="jsLoginTips">{{ loginform.errors.password}}</div>
                {% endif %}

                    <div class="error btns login-form-tips" id="jsLoginTips">{{ msg }}</div>
                    <div class="auto-box marb38">

                        <a class="fr" href="forgetpwd.html">忘记密码?</a>
                    </div>
                    <input class="btn btn-green" id="jsLoginBtn" type="submit" value="立即登录 > "/>
                    <input type='hidden' name='csrfmiddlewaretoken' value='5I2SlleZJOMUX9QbwYLUIAOshdrdpRcy'/>
                    {% csrf_token %}
                </form>

-前端判断用户状态

{% if request.user.is_authenticated %}

session

#settings中
'django.contrib.sessions',#该应用自动处理request请求与post,处理sessionID以及post的时候自动发送sessionID

HTML 中的路径问题

/static/css # 从顶层目录开始
./          #从本层目录开始
../         #从上层目录开始
  • 使用django 的相对路径标签
    优点是当静态文件目录放生变动时不用进入前端代码修改
<html>
{% load staticfiles %}#在html中首先加载静态文件标签,前后要有一个空格
<head>
# 表示后面的路径在setting 中设置静态文件的目录下
src="{% static 'images/dig_close.png' %} "# 相对路径前面不加/
#后面修改静态文件的目录名称时候只修修改settings.py中的设置,如下:
STATIC_URL = '/static/'
STATICFILES_DIRS =(os.path.join(BASE_DIR, 'static'),)
# 表示从url中获取相对路径
href="{% url 'register' %}"

django 验证库

pip install django-simple-captcha==0.4.6
# 在forms.py中创建类
from captcha.fields import CaptchaField
class RegisterForm(forms.Form):
    email = forms.EmailField(required=True)
    password = forms.CharField(min_length=3)  # 最小长度为3
    captcha = CaptchaField()
# 配置路径
 url(r'^captcha/', include('captcha.urls')),
 # 在处理函数中实例化类
 class RegisterView(View):
    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.email = user_name
            user_profile.username = user_name
            user_profile.password = make_password(pass_word)# 对密码进行加密保存,因为django 只存密文
            user_profile.save()
        else:
            return render(request,'register.html',{'register':register_form})
        return render(request, 'register.html')

    def get(self, request):
        register_form = RegisterForm()
        return render(request, 'register.html', {'register_form': register_form})

#修改HTML
<label>验&nbsp;证&nbsp;码</label>
{{register_form.captcha }}    
  • 上面jinja里面实际生成了相应的HTML代码,查看页面源代码如下:
    这里写图片描述
  • 简要总结:
    • forms.py里面的处理类字段必须和HTML里面的一直,否则验证不会通过
    • 出问题多debug仔细看提示

匹配网址参数

  • 路由设置
url(r'^active/(?P<active_code>.*)/$', ActiveUserView.as_view(), name='user_active'),
#对应的get函数
class ActiveUserView(View):
    def get(self,request,active_code):#注意这里的active_code要和路由里面的一致

前端相应代码

# 错误红框提示
<div class="form-group marb20 {% if loginform.errors.username %} errorput {% endif %}">
#每个from表单都会要求防止csrf
{% csrf_token %}
</form>

配置media文件路径

  • 在根目录下创建名为media的文件夹
  • settings.py 设置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
  • 引入处理库
TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                ...
                'django.core.context_processors.media',
            ],
        ...
]
  • 设置路由
url(r'^media/(?P<path>.*)$', serve, {"document_root":MEDIA_ROOT}),
  • 在HTML中使用

pure-pagination分页库使用

安装设置参照

                    <div class="pageturn">
                        <ul>
                            {% if courses.has_previous %}
                                <li class="long"><a href="?{{ courses.previous_page_number.querystring }}">上一页</a></li>
                            {% endif %}

                            {% for page in courses.pages %}
                                {% if page %}
                                    {% ifequal page courses.number %}
                                        <li class="active"><a class="page">{{ page }}</a></li>
                                    {% else %}
                                        <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li>
                                    {% endifequal %}
                                {% endif %}
                            {% endfor %}

                            {% if courses.has_next %}
                                <li class="long"><a href="?{{ courses.next_page_number.querystring }}">下一页</a></li>
                            {% endif %}
                        </ul>
                    </div>
  • views.py
#coding:utf8
from pure_pagination import Paginator, PageNotAnInteger
class CoursesView(View):
    def get(self,request):
        #获取当前页数,如果为分页则设置页数

        all_courses = Course.objects.all()
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(all_courses, 6, request=request)
        courses = p.page(page)
        course_count = all_courses.count()
        return render(request,'course-list.html',locals())
# 注意数据迭代也要改一下
{% for course in courses.object_list %}

django temple 过滤器

  • 更多请谷歌,这里记录用到的
int|stringformat:"i" #将int类型的数据转换成字符型

django 排序

hot_orgs = CourseOrg.objects.all().order_by("-click_nums")[:5]

数据库同步错误

  • 出现解决办法
python manage migrate --fake
  • 防患于未然
course_org = models.ForeignKey(CourseOrg,verbose_name=u'课程所属机构',null=True,blank=True)#这样做是保证没该字段之前添加的数据允许为空,或者增加default=''属性。

Django ModelForm

  • 相比之前的ModelForm更为简单并自带save
#之前form
class ModifyForm(forms.Form):
    password1 = forms.CharField(min_length=3)  # 最小长度为3
    password2 = forms.CharField(min_length=3)  # 最小长度为3
# 
class ModifyPwdView(View):#由于上面的路径设置必须要
    def post(self,request):
        modify_form  = ModifyForm(request.POST)
        if modify_form.is_valid():
            if request.POST.get('password1','') != request.POST.get('password2',''):
                return render(request,'password_reset.html',{'msg':'两次输入密码不一致'})
            email  = request.POST.get('email','')
            users = UserProfile.objects.filter(email=email)
            for user in users:
                user.password= make_password(request.POST.get('password1',''))
                user.save()
            return render(request,'index.html')
        else:
            return render(request, 'login.html')

#
继承forms.Form后还要对字段进行验证,在View里面还要save,但继承forms.ModelForm就简单多了,如下:

from operation.models import UserAsk

class UserAskForm(forms.ModelForm):
    class Meta:
        model = UserAsk # 指定forms对应的model
        fields=['name','mobile','course_name'] #指定form要验证的字段
#
class AddUserAskView(View):
    def post(self,request):
        userask_form = UserAskForm(request.POST)
        if userask_form.is_valid():
            user_ask = userask_form.save(commit=True)#这样就保存到了数据库,和之前比不用先实例化在保存。
            pass
  • django ModelForm 还可以进行自定义的格式筛选
class UserAskForm(forms.ModelForm):
    class Meta:
        model = UserAsk # 指定forms对应的model
        fields=['name','mobile','course_name'] #指定form要验证的字段

    #验证手机号码有效性,下面函数定义为固定格式
    def clean_mobile(self):
        moblie = self.cleaned_data['mobile']#获取填入的moblie
        #创建正则表达
        REGEX_MOBILE = "^1[358]\d{9}|^147\d{8}$|^176\d{8}$"
        p = re.compile(REGEX_MOBILE)

        if p.match(moblie):#如果匹配成功
            return moblie
        else:
            #下面的错误返回格式也是固定的
            raise forms.ValidationError(u"手机号码非法",code='mobile_invalid')

django ajax

  • ajax流程以收藏为例
点击页面收藏按钮-->ajax通过class或id绑定监听-->ajax从当前路径下调用函数-->后台函数处理并返回json-->ajax依据json做出相应显示
----------
#通过id监听

按键标签
<div class="btns">
    <div class="btn colectgroupbtn" id="jsLeftBtn">
        收藏
    </div>
<div class="buy btn"><a style="color: white" href="course-video.html">开始学习</a></div>
</div>

ajax函数
function add_fav(current_elem, fav_id, fav_type){
    $.ajax({
        cache: false,
        type: "POST",
        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.html";
                }else{
                    alert(data.msg)
                }

            }else if(data.status == 'success'){
                current_elem.text(data.msg)
            }
        },
    });
}

ajax监听,此处为通过id监听,通过class监听为$('.jsLeftBtn').on...
$('#jsLeftBtn').on('click', function(){
    add_fav($(this), {{ course.id }}, 1);
});

后台处理路径及函数
urlpatterns = [
...
    url(r'^add_fav/',AddFavView.as_view(),name='add_fav' ),
]

class AddFavView(View):
    """
    用户收藏以及取消收藏
    """

    def post(self, request):
        fav_id = request.POST.get('fav_id', 0)
        fav_type = request.POST.get('fav_type', 0)
        user_id = request.user.id
        # 首先判断用户是否登录
        if not request.user.is_authenticated:
            # 如果没有登录则返回没有登录信息
            return HttpResponse('{"status":"fail","msg":"用户未登录"}', content_type='application/json')
        else:
            # 如果用户登录了则判断之前有没有收藏过,如果重复收藏即意味着要取消收藏
            from operation.models import UserFavorite
            user_fav = UserFavorite.objects.filter(user_id=user_id, fav_id=int(fav_id), fav_type=int(fav_type))
            if user_fav:  # 如果之前收藏过则取消收藏
                user_fav.delete()
                # 返回取消收藏相关信息
                return HttpResponse('{"status":"fail","msg":"已取消收藏"}', content_type='application/json')
            else:  # 用户之前为收藏过,则进行收藏
                # 创建对象,实例化,保存极为收藏
                if int(fav_id) > 0 and int(fav_type) > 0:
                    userFav = UserFavorite()
                    userFav.fav_type = fav_type
                    userFav.fav_id = fav_id
                    userFav.user_id = user_id
                    userFav.save()
                    return HttpResponse('{"status":"success","msg":"收藏成功"}', content_type='application/json')
                else:
                    return HttpResponse('{"status":"fail","msg":"收藏失败"}', content_type='application/json')

html中传递路径参数加空格

<a href="{% url org:org_home org.id %}">

Django 判断用户是否登录

  • 全局搜索
    edit->find->find in path 快捷键 shift + command + F
{% if request.user.is_authenticated %}#此处的user是浏览器中的匿名对象,用来判断登录状态

错误解决6

使用分页的时候总提示函数参数不对,要求一个整型变量,却给了一个request,仔细对照了之前写的分页,并且查看了函数的源码,发现代码以及逻辑没有问题,弄了半天发现出错的这块源码函数就没有要求request,但之前的要求了request,发现时使用库的时候引用错了,应该使用pure….这个库。

数据类型choices类型的在html中显示的方法

degree = models.CharField(max_length=50,choices=(('cj', u'初级'), ('zj', u'中级'), ('gj', u'高级')))


----------

<span class="fl">难度:<i class="key">{{ course.get_degree_display }}</i></span>

Django QuerySet 外键反取

  • 关于Django的外键我有话要说
发现django的外键一般是自己的上级,从来不存下级的外键(这好像有点势力)
但当要取出下级的数据时候就要用反取,具体如下:(取出课程下面的章节)
# models里面设置
并且上级在反调的时候也不用导入下级的包
class CourseOrg(models.Model):
    name = models.CharField(max_length=20, 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=200)
    address = models.CharField(max_length=150, verbose_name=u'机构详细地址')
    city = models.ForeignKey(CityDict, verbose_name=u'机构所在城市')
    desc = models.CharField(max_length=300, verbose_name=u'描述')
    add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')
    category = models.CharField(max_length=20, default='pxjg', choices=(('pxjg', '培训机构'), ('gx', '高校'), ('gr', '个人'),),
                                verbose_name='机构类别')
    students = models.IntegerField(default=0, verbose_name='学习人数')
    course_nums = models.IntegerField(default=0, verbose_name='课程数量')

    class Meta:
        verbose_name = u'机构表'
        verbose_name_plural = verbose_name
    # 返回机构下面所有的课程
    def course_org_course_num(self):
        return self.course_set.all().count()
    #获取机构下面的教师数
    def course_org_teacher_num(self):
        return self.teacher_set.all().count()
    def __unicode__(self):
        return self.name
# 在html 中通过机构实例可以调用
{{ course_org.course_org_course_num}}
{{ course_org.course_org_teacher_num}}

重写View验证登录状态

新建一个用于判断登录状态的类,然后让处理类继承
from django.contrib.auth.decorators import login_required
from  django.utils.decorators import method_decorator

class LoginRequestedMixin(object):#mixin一般表示基础的view类
    @method_decorator(login_required(login_url='/login/'))
    def dispatch(self,request,*args,**kwargs):
        return super(LoginRequestedMixin,self).dispatch(request,*args,**kwargs)

# 处理函数继承基础view就会自动验证是否登录,未登录就跳转到指定页面
class CommentView(LoginRequestedMixin,View):
    def get(self,request,course_name):
        course = Course.objects.get(name=course_name)
        return render(request,'course-comment.html',locals())

使用video.js 打造视频播放页面

  • 首先下载video.js将相应的文件放到与HTML中路径对应的文件里面
    这里写图片描述
{% block custom_css %}
   ...
    <link rel="stylesheet" type="text/css" href=" {% static 'css/video-js.min.css' %} "/>
    <style>
        .video-js .vjs-big-play-button{
            letf:50%;
            right:50%;
        }
    </style>
{% endblock %}
<script src ="{% static 'js/video.min.js' %}" type ="text/javascript"></script>
{% block custom_js %}
  • 播放页面对应设置
# 此处视频是放到七牛云上生成的外链
 <div style="width:1200px;height:6750px;margin: auto ">
            <video id="example_video_1" class="video-js vjs-default-skin" width="1200" poster="http://video-js.zencoder.com/oceans-clip.png" data-setup="{}" controls preload="none">
                <source src="{{ video.link }}" type="video/mp4">
            </video>

        </div>
    <div id="main">

html中的切片

# 切路径后7位判断是否与后面字符串相等
{% request.path|slice:'7' =='/source' %}

顶部搜索框实现

  • 包含实现对搜索按键监听的js文件
<script src="/static/js/deco-common.js" type="text/javascript"></script>


----------
//顶部搜索栏搜索方法
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/teachers/list?keywords="+keywords
    }else if(type == "org"){
        request_url = "/org/list?keywords="+keywords
    }
    window.location.href = request_url
}
# 通过id监听
$('#jsSearchBtn').on('click',function(){
    search_click()
});

# 然后在对应的处理View里面进行处理
        if request.GET.get('keywords'):
            keywords = request.GET.get('keywords')
            teachers = Teacher.objects.filter(Q(name__icontains=keywords)|Q(work_company__icontains=keywords))

修改密码

  • 分析
    开始想用继承自forms.FormModel进行验证,结果发现继承自forms.Form的fields里面的参数必须和数据库以及form表单里面的三者一致,出现了一些麻烦,后改为继承forms.Model的表单验证。
class UserAskForm(forms.ModelForm):
    class Meta:
        model = UserAsk # 指定forms对应的model
        fields=['name','mobile','course_name'] 
        #指定form要验证的字段,数据库、此处、form表单三处要一致

    #验证手机号码有效性,下面函数定义为固定格式
    def clean_mobile(self):
        moblie = self.cleaned_data['mobile']#获取填入的moblie
        #创建正则表达
        REGEX_MOBILE = "^1[358]\d{9}|^147\d{8}$|^176\d{8}$"
        p = re.compile(REGEX_MOBILE)

        if p.match(moblie):#如果匹配成功
            return moblie
        else:
            #下面的错误返回格式也是固定的
            raise forms.ValidationError(u"手机号码非法",code='mobile_invalid')
  • 保存密码的时候要使用函数进行加密保存啊,不能直接保存,要不然自己都不知道自己改了个啥,—_—!
from django.contrib.auth.backends import ModelBackend
...
    if password1==password2:
        user.password = make_password(password1)
  • 在js文件中要手动配置路径
    这里写图片描述

HttpResponseRedirect()

  • 不仅可以避免硬编码而且可以避免缓存不能用问题
from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseRedirect

----------

class LogoutView(View):
    def get(self, request):
        users = UserProfile.objects.filter(username=request.user.username)
        for user in users:
            logout(request)
        return HttpResponseRedirect(reverse('index'))
# reverse是依据给定的视图返回对应路径,避免硬编码。

配置404/500页面

  • 在urls.py中配置页面路径
#全局404、500页面配置
handler404 = 'users.views.page_not_found'
handler500 = 'users.views.http_error'
  • 设置处理函数
# 404 全局处理函数
from django.shortcuts import render_to_response
def page_not_found(request):
    # 创建响应对象
    response = render_to_response('404.html',{})
    response.status_code=404
    return response
# 500 全局处理函数
def http_error(request):
    response = render_to_response('500.html',{})
    response.status_code=500
    return response
  • 此时如果不关闭debug模式,仍然访问不到配置好的页面,所以此时要关闭debug模式,但,关闭后回到是Django不会自动的通过之前配置的静态文件路径去找静态文件,这些事情将交给web服务器,所以此处为了体验效果,手动设置静态文件路径
DEBUG = False
# 用*表示匹配所有IP访问
ALLOWED_HOSTS = ['*']
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
STATIC_ROOT = os.path.join(BASE_DIR,'static')

xadmin 配置

  • 下载最新的font Awesmoe 解压后替换项目中的对应文件
    这里写图片描述
  • 到font Awesmoe网站查取想要图标对应的编码
  • 到对应的位置替换
    • 顶级目录图标替换
      这里写图片描述
      这里写图片描述

      class UserAdmin(object):
      change_user_password_template = None
      list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
      list_filter = ('is_staff', 'is_superuser', 'is_active')
      search_fields = ('username', 'first_name', 'last_name', 'email')
      ordering = ('username',)
      style_fields = {'user_permissions': 'm2m_transfer'}
      # model_icon = 'fa fa-user'
      model_icon = 'fa fa-user-o'#重点看这块
      relfield_style = 'fk-ajax'
    • 子目录图标修改
      到对应app的adminx.py下面进行替换
  • 字段选项设置
    • 设置字段默认排列顺序、读写性、显示。

      class BannerAdmin(object):
      list_display = ['title', 'image', 'url', 'index', 'add_time']
      search_fields = ['title', 'image', 'url']
      list_filter = ['title', 'image', 'url', 'index', 'add_time']
      ordering = ['-add_time'] #按时间倒序排列
      readonly_fields= ['title']#只读不能改
      exculde=['url']#不显示哪个字段
posted @ 2017-10-15 23:42  icanactnow  阅读(588)  评论(0编辑  收藏  举报