• python Django 学习笔记(六)—— 写一个简单blog做增删改练手


    简单效果图

     

    1,创建一个项目myblog 可参考这里

    myblog/
      manage.py
      myblog/
          __init__.py
          settings.py
          urls.py
          wsgi.py

    2,创建blogs app 可参考这里

    myblog/myblog/blogs/
        __init__.py
        models.py
        tests.py
        views.py
    • 编写models.py
    #vim: set fileencoding=utf-8:
    
    from django.db import models
    
    # Create your models here.
    
    class Blog(models.Model):
        title     = models.CharField(u'标题', max_length=50)
        author     = models.CharField(u'作者', max_length=10)
        content   = models.CharField(u'正文', max_length=2000)
        post_date  = models.DateTimeField(u'发布时间',auto_now_add=True)
    
        class Meta:
            ordering = ['-post_date']
    • 模型安装(修改settings.py)
    import os.path #加载模版需要导入库
    
    #数据库连接
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
            'NAME': 'myblog',                      # Or path to database file if using sqlite3.
            # The following settings are not used with sqlite3:
            'USER': 'root',
            'PASSWORD': 'root',
            'HOST': '127.0.0.1',                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
            'PORT': '3306',                      # Set to empty string for default.
        }
    }
    
    #模型安装
    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # Uncomment the next line to enable the admin:
        'django.contrib.admin',
        'myblog.blogs',
        # Uncomment the next line to enable admin documentation:
        # 'django.contrib.admindocs',
    )
    
    #加载模版
    TEMPLATE_DIRS = (
        # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
        # Always use forward slashes, even on Windows.
        # Don't forget to use absolute paths, not relative paths.
         os.path.join(os.path.dirname(__file__), 'templates').replace('\','/'),
    )
    
    MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',  #csrf防御,post提交跨站请求伪造
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    )
    
    
    
    #settings.py基本修改就这些了
    • 采用 python manage.py validate 检查模型的语法和逻辑是否正确。

      没有错误则执行 python manage.py syncdb创建数据表。

    3,编写forms.py

    myblog/myblog/forms.py

    #vim: set fileencoding=utf-8:
    
    from django import forms
    
    class BlogForm(forms.Form):
        title =  forms.CharField(label='标题')
        author = forms.CharField(label='作者')
        content = forms.CharField(label='正文',widget=forms.Textarea)

     4,编写views.py

    myblog/myblog/views.py

    #vim: set fileencoding=utf-8:
    
    from django.http import HttpResponseRedirect
    from django.shortcuts import render_to_response
    from myblog.blogs.models import Blog
    from myblog import forms
    from django.template import RequestContext
    
    def blog_list(request):
        blog_list = Blog.objects.all()
        return render_to_response('blog_list.html',{'blog_list':blog_list})
    
    def blog_form(request):
        if request.method == 'POST':
            form = forms.BlogForm(request.POST)
            if form.is_valid():
                data = form.cleaned_data
                if 'id' not in data: 
                    blog = Blog(title=data['title'],author=data['author'],content=data['content'])
                    blog.save()
                else:
                    blog = Blog.object.get(id=data.id)
                    blog.title = data['title']
                    blog.author = data['author']
                    blog.content = data['content']
                    blog.save()
                return HttpResponseRedirect('/blog/list')    
        else:
            form = forms.BlogForm()
            return render_to_response('blog_form.html',{'form':form},context_instance=RequestContext(request))
    
    def blog_del(request):
        errors = []
        if 'id' in request.GET:
            bid_ = request.GET['id']
            Blog.objects.filter(id=bid_).delete()
            return HttpResponseRedirect('/blog/list')
        else:
            errors.append("参数异常请刷新后重试")
            return render_to_response('blog_list.html', {'errors': errors})
    
    def blog_view(request):
        errors = []
        if 'id' in request.GET:
            bid_ = request.GET['id']
            blog = Blog.objects.get(id=bid_)
            return render_to_response('blog_view.html',{'blog':blog})
        else:
            errors.append("参数异常请刷新后重试")
            return render_to_response("blog_list.hmtl",{'errors':errors})
    
    def blog_edit(request):
        errors = []
        if 'id' in request.GET:
            bid_ = request.GET['id']
            blog = Blog.objects.get(id=bid_)
            form = forms.BlogForm(
                    initial = {'id':blog.id,'title':blog.title,'author':blog.author,'content':blog.content}        
            )
            return render_to_response('blog_form.html',{'form':form},context_instance=RequestContext(request))
        else:
            errors.append("参数异常请刷新后重试")
            return render_to_response("blog_list.html",{'errors':errors})

    5,创建模版文件

    myblog/myblog/templates/
                  blog_form.html
                  blog_list.html
                  blog_view.html
                
    
    
    #blog_form.html
    <html>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>博客编辑</title>
        <head></head>
        <body>
           {% if errors %}
            <ul>
                {% for error in errors %}
                <li style="color: red;">{{error}}</li>
                {% endfor %}
            </ul>
            {% endif %}
        <a href="/blog/list">返回主页>></a><p/>
        <form action="/blog/form" method="post">
           {% csrf_token %}
           <table>
                {{ form.as_table }}
            </table>
            <input type="submit" value="保存">
        </form>       
           
        </body>
    </html>
    
    
    #blog_list.html
    <html>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>主页-博客列表</title>
        <head></head>
        <body>
           {% if errors %}
            <ul>
                {% for error in errors %}
                <li style="color: red;">{{error}}</li>
                {% endfor %}
            </ul>
            {% endif %}
        <a href="/blog/form">去写博客>></a><p/>
           <table cellpadding="0" cellpadding="0" width="100%" border="1" >
            <tr height="20">
                <td>编号</td>
                <td>标题</td>
                <td>作者</td>
                <td>发布时间</td>
                <td>操作</td>
            </tr>
            {% for blog in blog_list %}
            <tr>
                <td>{{forloop.counter}}</td>
                <td><a href="/blog/view?id={{blog.id}}">{{blog.title}}</a></td>
                <td>{{blog.author}}</td>
                <td>{{blog.post_date | date:"Y-m-d H:i:s"}}</td>
                <td><a href="/blog/edit?id={{blog.id}}">修改</a>&nbsp;<a href="/blog/delete?id={{blog.id}}">删除</a></td>
            </tr>    
            {% empty %}
            <tr><td colspan="4">还没有添加博客内容</td></tr>    
            {% endfor %}
            
        </table>
        </body>
    </html>
    
    
    #blog_view.html
    <html>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>{{blog.title}}</title>
        <head></head>
        <body>
           {% if errors %}
            <ul>
                {% for error in errors %}
                <li style="color: red;">{{error}}</li>
                {% endfor %}
            </ul>
            {% endif %}
        <a href="/blog/list">返回主页>></a><p/>
           
        <h2>{{blog.title}}</h2>
        <p>作者:{{blog.author}}&nbsp;&nbsp;{{blog.post_date | date:'Y-m-d H:i:s'}}<p>
        <p>{{blog.content}}</p>
        </body>
    </html>

     6,修改urls.py

    from django.conf.urls import patterns, include, url
    from myblog import views
    
    # Uncomment the next two lines to enable the admin:
    # from django.contrib import admin
    # admin.autodiscover()
    
    urlpatterns = patterns('',
        # Examples:
        # url(r'^$', 'myblog.views.home', name='home'),
        # url(r'^myblog/', include('myblog.foo.urls')),
    
        # Uncomment the admin/doc line below to enable admin documentation:
        # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    
        # Uncomment the next line to enable the admin:
        # url(r'^admin/', include(admin.site.urls)),
        url(r'^blog/list$', views.blog_list),
        url(r'^blog/form$', views.blog_form),
        url(r'^blog/delete$', views.blog_del),
        url(r'^blog/view$', views.blog_view),
        url(r'^blog/edit$', views.blog_edit),
    )

     7,启动开发服务器 http://127.0.0.1:8000/blog/list

    8,遇到的问题

    1,CSRF verification failed. Request aborted.

    Forbidden (403)
    CSRF verification failed. Request aborted.
    Help
    Reason given for failure:
        CSRF token missing or incorrect.
        
    In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
    Your browser is accepting cookies.
    The view function uses RequestContext for the template, instead of Context.
    In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
    If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
    You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
    You can customize this page using the CSRF_FAILURE_VIEW setting.

    解决方法:

    • 在视图函数里用RequestContext类代替Context。RequestContext是Context的子类,具体可自行google。
    • 在模版表单中插入 {% csrf_token%}

       (本例子采用以上方法,可查看views.py 中blog_form()函数,和blog_form.html模版页面)

     

      另外也可以注释掉settings.py  

      #'django.middleware.csrf.CsrfViewMiddleware', #csrf防御,post提交跨站请求伪造

    2,还有个问题,就是在修改的时候怎么把对应id传入模版blog_form.html页面。暂未解决..

  • 相关阅读:
    Scala语言
    Eclipse的各种问题
    Java:
    Come on
    问题:实现继承的抽象方法
    Android:报错AndroidManifest.xml file missing
    正则表达式
    Android:相对布局Relativeyout中的属性解释
    Android:生命周期案例
    Android:设置APP全屏、横屏、竖屏、常亮的方法
  • 原文地址:https://www.cnblogs.com/wendoudou/p/myblog.html
Copyright © 2020-2023  润新知