用Python和Django制作一个简易的待办事项清单

在使用Django开发应用程序时

上次在Django上为自己创建的Twitter客户端http://qiita.com/Gen6/items/11fa5265053da95fcf0b

我做了一个项目,这次想要创建一个基于SQLite的简易待办事项清单应用程序。为了保留自定义的空间,我尽量采用了简洁的结构。也许还可以改进,例如从待办事项清单中向自己发送Twitter回复等。

通过利用Django的表单,我们将创建一个顾客管理系统、公告板或类似SNS的简易应用程序等。一旦掌握了这一概念,你将能够大大扩展应用的范围。

请参阅以下的文章以了解如何开始使用 Django:http://qiita.com/Gen6/items/1848f8b4d938807d082e

筹备工作

假设已经安装了Python3和Django,并且已经安装了virtualenv,我们将在此基础上进行。如果您还没有做好前期准备,请参考过去的文章进行准备工作。

创建项目

创建一个名为orders的Django项目,并在其中创建一个名为myapp的子目录。

virtualenv) $ django-admin startproject orders
virtualenv) $ cd orders
virtualenv) $ python manage.py startapp myapp

请确认 orders 目录下是否创建了 myapp 和 orders。

进行初始设定

订单目录的操作

请参考以下内容在settings.py中进行编写。数据库将直接使用SQLite3。


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

STATIC_URL = '/static/'

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

url.py的中文释义

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^myapp/', include('myapp.urls')),
    url(r'^', include('myapp.urls',namespace='myapp')),
    url(r'^admin/', admin.site.urls),
]

设定命名空间将来会变得很方便。
养成使用命名空间的习惯会很不错。

在myapp文件夹下的工作

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
]

创建应用程序

模型的定义

这次是一个简单的 To-do List,我们将利用 Django 中内置的表单进行操作,所以我们会简单地定义模型。models.DateTimeField() 很方便。

from django.db import models

class Posting(models.Model):
    message = models.CharField(
        max_length = 140,
        verbose_name = 'やること',
    )

    created_at = models.DateTimeField(
        auto_now_add = True,
        verbose_name= '日時',
    )

我将通过文本接收任务并自动填写日期和时间。我设定接收的字符数为140个字符。

准备表格。

在目录中新增创建一个新的文件夹。

from django import forms
from myapp.models import Posting


class PostingForm(forms.ModelForm):

    class Meta:
        model = Posting
        fields = ('message',)
        widgets = {
            'message': forms.Textarea(attrs={'cols': 40, 'rows': 4})
        }

在表单字段中,除了To-do以外还有其他可用字段,但由于这次只涉及To-do,所以采用了这样的描述。在widgets中,可以设定在将其导出为HTML时文本区域的大小等。

进行对视图的描述

通过import导入模型类和Django的PostingForm。
由于本次没有页面跳转,我们将使用redirect()函数。你可能会理解为什么要设置命名空间了。

import sys, codecs
sys.stdout = codecs.getwriter('utf-8')(sys.stdout)

from django.http.response import HttpResponse
from django.shortcuts import (render, redirect,)
from django import forms
from myapp.models import Posting
from .forms import PostingForm

def index(request):
    form = PostingForm(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            form.save()
            return redirect('myapp:index')
    new_text = Posting.objects.all().order_by('-id')
    contexts = {
        'form':form,
        'new_text':new_text,
    }
    return render(request, 'index.html', contexts)

这里

new_text = Posting.objects.all().order_by('-id')

根据应用的需求,编写以逆序显示数据库内容的指令,请尝试使用不同的.order_by()方法。

contexts = {
        'form':form,
        'new_text':new_text,
    }

我建议将Django的表单传递到这里。同时,为了显示数据库的内容,将这两个字典作为render函数的第三个参数。我认为最好是通过字典不断地传递需要在模板中使用的内容。

将admin.py进行设置

from django.contrib import admin
from myapp.models import Posting


class PostingAdmin(admin.ModelAdmin):
    list_display = ('id','message','created_at')

admin.site.register(Posting,PostingAdmin)

为了在Django管理网站上进行确认,请设置显示项目。

list_display = (‘id’,’message’,’created_at’)

通过这样写,可以显示id、消息和创建日期。

准备HTML模板

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="../static/css/bootstrap.min.css" rel="stylesheet">
    <link href="../static/css/custom.css" rel="stylesheet">
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="../static/js/bootstrap.min.js"></script>
    <title></title>
  </head>
  <body>
    {% block body %}
    {% endblock %}
  </body>
</html>

这是基础共享组件。
我们将Bootstrap放在static目录中。可以为模板编写链接结构,但我仍按照传统的方式进行了编写,以供参考。

{% static 'css/custom.css' %}

可以对此进行如下描述。

{% extends "base.html" %}
{% block body %}
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        <form action="{% url 'myapp:index' %}" method="post">
          <div class="row">
            {% for field in form %}
            <label class="col-sm-3">{{ field.label_tag }}</label>
            <label class="col-sm-7">{{ field }}</label>
            {% endfor %}
            <input type="submit" class="btn btn-primary" value="登録">
            {% csrf_token %}
            </div>
          </div>
        </form>
        {% include "to_do.html" %}
      </div>
    </div>
  </div>
{% endblock %}

这是用来显示表单的主要HTML文件。
为了显示输入的待办事项列表,将包含另一个HTML文件。

由于在urls.py中设置了命名空间,所以

<form action="{% url 'myapp:index' %}" method="post">

学会能够以这种方式写作非常方便!

{% csrf_token %} 

这是用于防止跨站请求伪造的措施。我们会在HIDDEN中嵌入密码学伪随机数值,如果忘记写入,就无法进行POST请求。务必在关闭表单之前进行设置。

<div class="row">
  {% for i in new_text %}
  <div class="col-md-4">
  <p>{{ i.message }} - {{ i.created_at }}</p>
  </div>
  {% endfor %}
</div>

这是在index.html中包含的内容。
只是简单地使用for循环遍历从数据库中获取的内容。

迁移

virtualenv) $ python manage.py makemigrations myapp
virtualenv) $ python manage.py migrate

应用程序界面

スクリーンショット 2016-11-14 13.11.43.png

已完成。

广告
将在 10 秒后关闭
bannerAds