Last time I made my own Twitter client with Django http://qiita.com/Gen6/items/11fa5265053da95fcf0b,
Now that I've done, I'd like to create a simple to-do list application using SQLite. I tried to make the configuration as simple as possible to leave room for customization. Is there room for modification such as sending a reply from the to-do list to myself on Twitter?
This time, I will make it using Django's Form. If I can understand this, I feel that the range of simple customer management systems, bulletin boards, SNS-like applications, etc. will expand dramatically.
See the article below for how to get started with Django in the first place. http://qiita.com/Gen6/items/1848f8b4d938807d082e
We will proceed on the assumption that Python 3 and Django are already installed and virtualenv is also installed. If you are not ready so far, please prepare by referring to past articles.
Let's make the Django project orders and create myapp under it.
virtualenv) $ django-admin startproject orders
virtualenv) $ cd orders
virtualenv) $ python manage.py startapp myapp
Make sure that myapp and orders are created in the orders directory.
Please describe the contents of settings.py with reference to the following. Use SQLite3 as it is for the database.
orders/settings.py
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
orders/urls.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),
]
It will be convenient later if you set the namespace. I think it's a good idea to get in the habit of adding a namespace.
myapp/ursl.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
This time it's a simple to-do list, but we'll take advantage of the forms built into Django, so we'll roughly define the model. models.DateTimeField () is useful.
myapp/models.py
from django.db import models
class Posting(models.Model):
message = models.CharField(
max_length = 140,
verbose_name = 'things to do',
)
created_at = models.DateTimeField(
auto_now_add = True,
verbose_name= 'Date and time',
)
We will receive the text of what to do and the date and time will be written automatically. I tried to receive up to 140 characters.
Create a new one in the directory.
myapp/forms.py
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})
}
There are other fields that can be used in the form fields, but this time it is only To-do, so it is described like this. You can set the size of the text area when it is exported to HTML with widgets.
Import the model class with import and import the Django Posting Form. Since there is no page transition this time, we will use redirect (). You can see why we set the namespace here.
myapp/views.py
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)
here
new_text = Posting.objects.all().order_by('-id')
I am writing an instruction to display the contents of the database in reverse order of ID. There are various ways to use .order_by (), so I wonder if I should change it depending on the application.
contexts = {
'form':form,
'new_text':new_text,
}
Pass in the Django form here. Since we want to display the contents of the database at the same time, we will use these two as the third argument of the render function. I think it's a good idea to pass more and more what you want to use in the template in the dictionary.
myapp/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)
Let's set the display items to check from the Django administration site.
list_display = ('id','message','created_at')
By writing in this way, you will be able to display the id, message, and posting date and time.
templates/base.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>
It is a common part that becomes the base. I have Bootstrap in a static directory. You can write the link structure for the template, but for reference, I tried to write it as usual.
{% static 'css/custom.css' %}
Such a description is possible.
tenplates/index.html
{% 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="Registration">
{% csrf_token %}
</div>
</div>
</form>
{% include "to_do.html" %}
</div>
</div>
</div>
{% endblock %}
This is the main HTML file that displays the form. Include another HTML file to display the to-do list you entered.
Since the namespace is set in urls.py,
<form action="{% url 'myapp:index' %}" method="post">
You will be able to write like this. It's convenient!
{% csrf_token %}
This is a cross-site request forgery countermeasure. Since we embed a cryptographically secure pseudo-random value in HIDDEN, we cannot POST if we forget to write this. Be sure to install it before closing the foam. Is it hard to forget if you place it just behind the