美文网首页网站开发python从入门到精通python 实战实验室
最新Django2.0.1在线教育零基础到上线教程(六)1-3

最新Django2.0.1在线教育零基础到上线教程(六)1-3

作者: 天涯明月笙 | 来源:发表于2018-01-20 19:40 被阅读2049次

    演示地址: http://mxonline.mtianyan.cn

    教程仓库地址1: https://github.com/mtianyan/DjangoGetStarted
    教程仓库地址2: https://github.com/mtianyan/Mxonline2
    教程仓库地址3: https://github.com/mtianyan/Mxonline3

    6-1 首页和登录页面的配置

    用户访问我们的根目录,我们需要把html文件返回给用户。因此我们第一步把html文件放入template目录。

    mark

    在html中找到首页的html。拷贝到我们的template目录

    mark

    新建static目录

    用来存放css, js等静态文件

    mark

    配置处理静态文件的url。

    Django2.0.1版本下:

    Mxonline3/urls.py:

    from django.views.generic import TemplateView
    
    urlpatterns = [
        path('xadmin/', xadmin.site.urls),
        # TemplateView.as_view会将template转换为view
        path('', TemplateView.as_view(template_name= "index.html"), name=  "index")
    ]
    

    Django1.9.8版本下:

    Mxonline2/urls.py:

    from django.views.generic import TemplateView
    
    urlpatterns = [
        url(r'^xadmin/', xadmin.site.urls),
        url('^$', TemplateView.as_view(template_name="index.html"), name="index")
    
    ]
    
    

    此时运行访问就可以访问到我们的index页面,不过会没有样式。

    设置static文件

    # 说明静态文件放在哪个目录
    
    STATIC_URL = '/static/'
    
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, "static"),
    )
    

    修改index页面中前端样式的引用地址

    mark

    使用ctrl+f查找出所有../,全部替换为/static/

    然后点击运行,刷新页面可以看到我们的页面已经显示正常了。

    拷贝登录页面到template

    mark

    使用ctrl+f查找出所有../,全部替换为/static/

    将css,js,图片全部替换完。

    url配置跳转登录页面

    Mxonline2/urls.py:

        # 登录页面跳转url
        url('^login/$', TemplateView.as_view(template_name="login.html"), name="login")
    

    Mxonline3/urls.py:

        # TemplateView.as_view会将template转换为view
        path('', TemplateView.as_view(template_name= "index.html"), name=  "index"),
        path('login/', TemplateView.as_view(template_name= "login.html"), name=  "login")
    

    在index页面,ctrl+f找到登录。将a标签中地址替换为login的url。

    mark

    取消注释后,将login.html改为/login/

    mark

    点击左侧减号收起。然后使用``将个人中心暂时注释。

    mark

    可以看到登录注册,点击登录。

    根路径下的所有url都不需要斜杠

    此时我们的首页已经可以成功显示,通过首页点击登录也可以成功跳转登录页面

    本小节完成对应commit:

    6-1: 完成首页与登录页面配置,设置了STATICFILES_DIRS。注意:dirs是一个元组,不要少逗号。删除了前面上传头像等直接传到根目录的目录。

    6-2 用户登录-1

    配置url之前我们要书写好对应处理的view

    Django的view实际就是一个函数,接收request请求对象,处理后返回response对象。

    users/views.py:

    # encoding: utf-8
    # 当我们配置url被这个view处理时,自动传入request对象.
    def login(request):
        # 前端向后端发送的请求方式: get 或post
    
        # 登录提交表单为post
        if request.method == "POST":
            pass
        # 获取登录页面为get
        elif request.method == "GET":
            # render就是渲染html返回用户
            # render三变量: request 模板名称 一个字典写明传给前端的值
            return render(request, "login.html", {})
    

    django1.9.8/urls.py

    from users.views import user_login
        # 登录页面跳转url login不要直接调用。而只是指向这个函数对象。
        url('^login/$',login, name="login")
    

    django2.0.1/urls.py:

    from users.views import login
        path('login/', login, name="login")
    

    在两行返回语句的位置打上断点:

    mark

    点击debug,进入首页后点击登录。可以看到

    mark

    说明确实是通过get请求请求页面的。

    通过值浏览器窗口可以看到这是一个<WSGIRequest: GET '/login/'>对象

    mark

    path:是指向的地址。

    f8继续运行。跳转到登录页面。

    6-3 用户登录2

    html form基础知识

    templates/login.html:

    可以看到form表单中有input。点击提交会把值提交到后台。我们需要修改action让它指向我们的后台相应地址。

    mark mark

    input中的name值会被传递到后台。回组成键值对形式。

    submit类型的input

    mark

    只保留post这里的断点。输入用户名密码。查看debug情况

    mark

    403禁止访问错误: html页面内必须加上crsf token 才能传值到后台。

    我会随机的给前端发一串符号,你必须把这串符号带回来,我才允许你post。

    mark

    from表单之前写上crsf token

    此时我们查看前端页面:

    mark

    可以看到html中登录下面有一个隐藏着的值:crsf token, 不会显示。

    此时点击登录跳转到pass位置。

    mark mark

    可以看到request中的POST中是一个queryset的对象。我们可以把它当成一个字典来用。
    来取到前端的数据

        if request.method == "POST":
            # 取不到时为空,username,password为前端页面name值
            user_name = request.POST.get("username", "")
            pass_word = request.POST.get("password", "")
    

    取到用户名和密码我们就要开始进行验证登录。使用Django自带的auth方法。

    from django.contrib.auth import authenticate, login
    
        # 登录提交表单为post
        if request.method == "POST":
            # 取不到时为空,username,password为前端页面name值
            user_name = request.POST.get("username", "")
            pass_word = request.POST.get("password", "")
    
            # 成功返回user对象,失败返回null
            user = authenticate(username= user_name, password= pass_word)
    
            # 如果不是null说明验证成功
            if user is not None:
                # login_in 两参数:request, user
                # 实际是对request写了一部分东西进去,然后在render的时候:
                # request是要render回去的。这些信息也就随着返回浏览器。完成登录
                login(request, user)
                # 跳转到首页 user request会被带回到首页
                return render(request, "index.html")
            # 没有成功说明里面的值是None,并再次跳转回主页面
            else:
                return render(request, "login.html", {})
    

    authenticate调用只需要传入用户名和密码。成功会返回user对象,失败返回null

    html中通过

    mark

    设置成如果登录显示个人中心那段,未登录显示登录注册

    打上断点

    mark

    点击debug后可以看到

    mark

    我们成功的取到了值。

    Django默认我们使用用户名和密码来登录

    成功的登录user值如下

    mark

    但是继续执行报错:

    login() takes exactly 1 argument (2 given)
    

    这时因为我们处理登录的自定义函数也叫login。就直接调用了自身,而不是调用Django提供的login。所以我们一定不要把自定义view函数命名与Django提供的冲突

    解决方案:将我们的login改为def user_login(request):

    并且前往urls.py中将login也一并改了

    此时运行可以看到我们的个人中心已经出来了。

    改造为使用邮箱用户名均可。Setting中重载变量

    自定义authenticate方法

    from django.contrib.auth.backends import ModelBackend
    from .models import UserProfile
    # 并集运算
    from django.db.models import Q
    
    # 实现用户名邮箱均可登录
    # 继承ModelBackend类,因为它有方法authenticate,可点进源码查看
    class CustomBackend(ModelBackend):
        def authenticate(self, username=None, password=None, **kwargs):
            try:
                # 不希望用户存在两个,get只能有一个。两个是get失败的一种原因 Q为使用并集查询
    
                user = UserProfile.objects.get(Q(username=username)|Q(email=username))
    
                # django的后台中密码加密:所以不能password==password
                # UserProfile继承的AbstractUser中有def check_password(self, raw_password):
    
                if user.check_password(password):
                    return user
            except Exception as e:
                return None
    

    Mxonline2/settings.py

    # 设置邮箱和用户名均可登录
    AUTHENTICATION_BACKENDS = (
        'users.views.CustomBackend',
    
    )
    
    mark

    使用xadmin的退出,注销当前用户的退出。

    此时我们可以通过邮箱和用户名都可以完成登录。

    用户提示:return页面时提供它的错误信息

    mark
    return render(request, "login.html", {"msg":"用户名或密码错误! "})
    

    Html中如何取到这个值;

    login html中这段是用来做错误提示的。

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

    验证:

    mark

    本小节结束对应commit:

    6-2&3 完成了用户登录,登录验证自定义:邮箱用户名均可。错误信息返回前端。设置登录显示个人中心判断,注意不要把自定义方法写成login。

    相关文章

      网友评论

      • Sunsmile_9ce0:能问你个问题吗?最近我写这个项目,验证码这块我传的是错误的值,但是debug的时候,error一直为None,什么原因可以造成这种结果
      • 张小二_tiny:通过login返回的 index 样式加载不上, 最后查看变成了 http://127.0.0.1:8000/login/static/css/reset.css,多出来一个路径
        张小二_tiny:已经解决了,页面写成了绝对路径,使用{% static %}相对路径就好了。感谢博主的热心解答
        天涯明月笙:@张小二_tiny Setting中的staticRoot 或 Static Dir设置有问题。
      • 303f9e16ed51:向“http://127.0.0.1:8000/static/js/jquery.min.js”的 <script> 加载失败。
        127.0.0.1:8000:14
        指向“http://127.0.0.1:8000/static/js/jquery-migrate-1.2.1.min.js”的 <script> 加载失败。

        页面还是没有格式
        天涯明月笙:@like528 {% load staticfiles %} 以及 {% static .... } setting中的STATICFILES_DIRS 一个都不能少。
      • ba28044025ed:index.html的样式在Safari和火狐都能正常显示,唯独在Google不能正常显示 你们有遇见这个问题吗?
        天涯明月笙:@逃学书生 具体是那部分的样式呢?有可能是缓存没清
      • TcAlan:{% if request.user.is_authenticated %} 这里好像写反了
        改成 {% if not request.user.is_authenticated %}

        另外一个 登录成功跳转首页的时候 应该要把user带到html里面吧
        return render(request,'index.html') 修改为 return render(request,'index.html',{'user':user})
        不知道其他小伙伴是否有遇到这个问题 我是这么修改后好了的
        天涯明月笙:@TcAlan 代码以我github为准,有时候有点出入改了代码忘记更新教程
      • 4f97d68c092f:我想问下楼主,我的代码和你一样,而且在debug模式下都有进到逻辑中,就是我登录账户密码是对的时候并没有跳转到主页,而是停留在登录页,但是换成127.0.0.1:8000/后在index页面显示是已登录了,请问怎么解决页面没有跳转这个问题?
        天涯明月笙:@XGP是西瓜皮 index页面已登录可能是浏览器缓存的cookie你换个浏览器调试一下
      • 7094bba22da4:6-3中“html中通过”指的是index.html中:
        {% if request.user.is_authenticated %}
        <div class="personal">
        <dl class="user fr">
        <dd>bobby<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>django</h2>
        <p>bobby</p>
        </dd>
        </dl>
        <div class="btn">
        <a class="personcenter fl" href="usercenter-info.html">进入个人中心</a>
        <a class="fr" href="/logout/">退出</a>
        </div>
        </div>
        </div>
        {% else %}
        <div class="wp">
        <div class="fl"><p>服务电话:<b>33333333</b></p></div>

        <a >  有</a>
        <a style="color:white" class="fr registerbtn" href="register.html">注册</a>
        <a style="color:white" class="fr loginbtn" href="/login/">登录</a>

        </div>
        {% endif %}
        流年扶苏:我在模板中用“/static/css/style.css”引用静态文件时死活找不到,后来改成{% load staticfiles %}后用“{% static "css/style.css" %}”就可以了。我用的django2.0.4 python3.6.2,希望能帮到有需要的路人。
        owolf:@Bugyou 在吗,找不到对应的啊,方便截张图吗
        7094bba22da4:{% if request.user.is_authenticated %}
        {%else%}
        {%endif%}
        找对应位置自行加上
      • 7094bba22da4:debug时把这行注销掉path('login/', TemplateView.as_view(template_name= "login.html"), name= "login"),不能给login()配两个url
      • 原来不语:感谢
        天涯明月笙:@原来不语 谢谢鼓励
      • 宗更:设置static文件

        # 说明静态文件放在哪个目录

        STATIC_URL = '/static/'

        STATICFILES_DIRS = (
        os.path.join(BASE_DIR, "static")
        )

        因为是元组所以要加 ' , ' 号!不然会报错!报错信息:
        ERRORS:
        ?: (staticfiles.E001) The STATICFILES_DIRS setting is not a tuple or list.
        HINT: Perhaps you forgot a trailing comma?

        System check identified 1 issue (0 silenced).
        宗更:@天涯明月笙 嗯!谢谢你啊!
        天涯明月笙:@宗更 已经修改了。元组一个元素的地方是要慎重注意的。 更多时候推荐能用list的地方用list替代。
      • 宗更:很感谢这位大神的总结!让我少走很多弯路!真的很感谢!
        另外:我在这里贴上没有修改过不是github里面的页面资源!
        希望能给后面学习的带来一点点帮忙
        链接: https://pan.baidu.com/s/1eSTUzyq 密码: zrr8
      • 大喵哥哥666:我的html中的if判断不生效
        大喵哥哥666:@大喵哥哥666 清了session就OK了😀
      • 54小时50分:兄弟写的非常详细,对于初学者的帮助很大,有了你的汗水,后来者更有信心学好python了,向你学习。
        天涯明月笙:@54小时50分 谢谢支持。加油。

      本文标题:最新Django2.0.1在线教育零基础到上线教程(六)1-3

      本文链接:https://www.haomeiwen.com/subject/mxotaxtx.html