美文网首页
Django 学习笔记 - 提交表单及发表文章

Django 学习笔记 - 提交表单及发表文章

作者: yipliksun | 来源:发表于2017-01-04 00:11 被阅读0次

    提交表单及发表文章

    提交表单

    1. html表单

    <form method="POST" action=""> {% csrf_token %}
        <input type="text" name="title" />
        <textarea name="content"></textarea>
        <button type="submit">发表</button>
    </form>
    
    • input 标签 自开自闭
    • textarea 标签 多行文本框 有开闭标签
    • submit 按钮 html表单 一定要有一个submit按钮
    • {% csrf_token %} 一定要写在form后面

    2. 后台处理

    if request.method == "GET":
        return render_to_response("xxx.html", 
        {},
        context_instance=RequestContext(request))
    else:
        title = request.POST["title"].strip()
        content = request.POST["content"].strip()
        # do anything
    

    csrf 跨站请求伪造

    • A为可信站点,B为危险站点。
    • 在A登录后,没有退出,然后访问B网站。
    • B网站伪造了一个表单,从用户的浏览器提交到A网站。提交到A网站的请求,浏览器会自动带上认证信息,结果A网站认证通过。
    • 如果这个请求是修改密码,用户的账号就被盗了。

    Django 防止CSRF

    • 给form表单添加一个隐藏字段,一个每个浏览器都不一样的随机码。
    • 后端验证随机码是否存在。
    • 危险网站无法提前探知随机码,也就无法伪造请求了。
    • {% csrf_token %}

    什么是context(环境)

    context_instance = RequestContext(request)
    
    • 没有来之前就已经存在的东西就是环境
    • 模板中不用定义就可以使用的变量就是环境
    • render_to_response 的第二个参数,那个字典,就是环境。
    • RequestContext(request) 是由请求对象提供的环境,提供了一些模板可以使用的变量,这些变量是从请求中解析出来的。csrf_token 就在其中。
    • from django.template import RequestContext

    位置参数与关键字参数

    • do_something(1) 位置参数
    • do_something(in=1, out=2) 关键字参数
    • do_something(1, out=2) 位置参数在前,关键字参数在后
    • def do_anything(*args, **kwargs): pass
    • args 是位置参数集合,是列表,*解列表为位置参数
    • kwargs 是关键字参数集合,是字典, ** 是解字典为关键字参数

    uls 与 reverse

    {% url 'URL名称' 位置参数 关键字参数=值 %}
    reverse('URL名称', args=[位置参数], kwargs={关键字参数})
    
    • 作用相同
    • url用于模板中,html中。
    • reverse 用于控制器中,python中。
    • 他们得到的返回值都是一样的,都是字符串,就是解析出来的url。

    消息组件

    from django.contrib import messages
    

    添加消息( 消息级别:DEBUG, INFO, SUCCESS, WARNING, ERROR)

    message.add_message(request, messages.ERROR, u'标题和内容不能为空')
    ...
    context_instance=RequestContext(request)
    

    消息展示

    {% if messages %}
        {% for message in messages %}
            <div class="alert alert-info"> {{ message }} </div>
        {% endfor %}
    {% endif %}
    
    • 消息只展示一次。
    • 给request变量增加了消息属性。
    • message增加在这个请求上面,然后这个请求包装成一个请求环境,传给了模板,所以模板上就有了这个消息。
    • message实际上是存在数据库中。在任何地方添加消息之后,如果你一直不输出,一直不在模板上展示这个消息,让这个消息一直存着,就算是这个请求返回之后,这个消息也不丢失,直到有一次,页面里面传入了请求的环境,然后再页面里面展示了消息,这些消息就会被展示出来(包括以前没有展示的)。

    帖子详情页面

    • 数据模型:已定义
    • URL:/article/detail/<article_id>
    • 控制器:展示一个页面
    • 模板:继承与base.html,用bootstrap美化,展示必要信息

    作业

    • 文章列表页面,增加“发表文章”的按钮
    • 增加发表文章的页面及功能
    • 发表成功/失败有消息提示
    • 文章列表页面,文章的标题为链接,可点击,点击跳转到文章详情
    • 完成文章详情

    /article/views.py 注意的代码

    from django.core.urlresolvers import reverse
    from django.contrib import messages
    from django.contrib.auth.models import User
    from django.shortcuts import render_to_response, redirect
    from django.template import RequestContext
    
    def create_article(request, block_id):
        block_id = int(block_id)
        block = Block.objects.get(id=block_id)
        if request.method == "GET":
            return render_to_response("article_create.html", {"b": block},
                                    context_instance=RequestContext(request))
        else:  # request.method == "POST"
            title = request.POST["title"].strip()
            content = request.POST["content"].strip()
            if not title or not content:
                messages.add_message(request, messages.ERROR, u"标题和内容均不能为空")
                return render_to_response("article_create.html",
                        {"b": block, "title": title, "content": content},
                        context_constance=RequestContext(request))
            owner = User.objects.all()[0]  # TODO:
            new_article = Article(block=block, owner=owner, title=title, content=content)
            new_article.save()
            messages.add_message(request, messages.INFO, u'成功发布文章')
            return redirect(reverse("article_list", args=[block.id]))
    

    注意:python str.format()格式化中文

    import sys
    reload(sys)  # 如果没法直接调用setdefaultencoding()方法就加上这句
    sys.setdefaultencoding('utf-8')

    相关文章

      网友评论

          本文标题:Django 学习笔记 - 提交表单及发表文章

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