Sau khi chia sẻ một chút về CRUD với nodejs thì hôm nay, mình sẽ chia sẻ thêm một chút CRUD về python với Django sử dụng Mysql. Và tất nhiên nội dung cơ bản mình chia sẻ chỉ nằm trong phạm vi dành cho những người bắt đầu học python mà thôi.
Trong bài viết này mình sử dụng Python 2.7.12, Django 1.11 có sử dụng Function views và Base views.
Vì mình chỉ chia sẻ một số chức năng cơ bản nên có thể sẽ thiếu sót trong quá trình chạy project ví dụ như chưa có Authentication, validate cho form,... nên các bạn có thể tự tìm hiểu thêm
1. Khởi tạo project Django
Điều đầu tiên cần làm là khởi tạo 1 project, trong ví dụ này mình sẽ tạo 1 project tên là myproject
:
~$ django-admin startproject myproject
Xong, chúng ta có cây thư mục như sau:
myproject
--myproject
----__init__.py
----settings.py
----urls.py
----wsgi.py
--manage.py
2. Cấu hình database MySql
Mở file settings.py
và tìm đến chỗ cáu hình db DATABASES
:
# settings.py
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': ,
'USER': ,
'PASSWORD': ,
'HOST': 'localhost',
'PORT': '',
}
}
...
Config xong, bạn cần migrate db bằng cách:
~$ python manage.py migrate
Và tạo một super user cho hệ thống của bạn:
~$ python manage.py createsuperuser
Sau khi tạo username
, email
, password
cho super user thì công việc tiếp theo là khởi chạy hệ thống:
~$ python manage.py runserver
Xong, khởi đầu thành công với //localhost:8000
3. Tạo module [app] mới.
Tiếp theo cần tạo một module hay cũng có thể gọi là 1 app mới cho hệ thống để chúng ta có thể dễ dàng hơn cho việc triển khai chức năng CRUD. Ở đây sẽ tạo module cho đối tượng Post.
~$ python manage.py startapp posts
Chúng ta sẽ có cây thư mục như sau:
#settings.py
INSTALLED_APPS = [
'posts',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
3.1. Cấu hình models
# posts/models.py
from __future__ import unicode_literals
from django.db import models
from django.core.urlresolvers import reverse
class Post[models.Model]:
name = models.CharField[max_length=224, null=False, blank=False]
content = models.TextField[max_length=254, null=False, blank=False]
timestamp = models.DateTimeField[auto_now_add=True]
updated = models.DateTimeField[auto_now=True]
def __unicode__[self]:
return self.content
Sau lần lượt chạy:
~$ python manage.py makemigrations
Sẽ thấy:
Migrations for 'posts':
posts/migrations/0001_initial.py
- Create model Post
Tieps theo là migrate:
~$ python manage.py migrate
4. CRUD
4.1 List Post
# posts/views.py
from __future__ import unicode_literals
from django.shortcuts import render, redirect
from django.views.generic import ListView
from .models import Post
class ListPostView[ListView]:
model = Post
def get [self, request, *args, **kwargs]:
template_name = 'posts/list-posts.html' # sẽ được tạo ở phần dưới
obj = {
'posts': Post.objects.all[]
}
return render[request, template_name, obj]
Trong urls.py
# posts/urls.py
from django.conf.urls import url
from django.contrib import admin
from posts.views import [
ListPostView,
]
urlpatterns = [
url[r'^list-posts/$', ListPostView.as_view[], name='list-posts'],
]
Để sử dụng namespace trong python, thì cần thêm vào myproject/urls.py
# myproject/urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url[r'^admin/', admin.site.urls],
url[r'^posts/', include['posts.urls', namespace='posts']],
]
Tiếp theo là template, ở đây mình sẽ hướng dẫn các bạn sử dụng layout luôn:
DOCTYPE html>
{% block title %}CRUD{% endblock title %}
footer {
background-color: #555;
color: white;
padding: 15px;
}
CRUD
List Posts
{% block content %}
{% endblock content %}
My Project CRUD Posts
Và đến posts/list-posts.html
{% extends "layouts/layout.html" %}
{% block title %}
List Post | {{ block.super }}
{% endblock title %}
{% block content %}
List Posts
{% if posts %}
{% for post in posts %}
{{post.name}}
Post at {{post.timestamp}}
{{post.content}}
{% endfor %}
{% else %}
No song.
{% endif %}
{% endblock content %}
Như vậy là chúng ta đã có thể xem list các bài post rồi. Nhưng hiện tại vẫn chưa có dữ liệu. Nào, bắt đầu thêm dữ liệu nhé.
4.2 Create Post
Để tạo được bài post, đầu tiên chúng ta nên tạo 1 file gọi là forms.py
:
# posts/forms.py
from django import forms
from .models import Post
class CreatePostForm[forms.ModelForm]:
class Meta:
model = Post
fields = ['name', 'content',]
Và urls thêm:
# posts/urls.py
...
from posts.views import [
ListPostView,
CreatePostView,
]
urlpatterns = [
url[r'^list-posts/$', ListPostView.as_view[], name='list-posts'],
url[r'^create-post/$', CreatePostView.as_view[], name='create-post'],
]
Quay lại với file views
# posts/views.py
...
from django.views.generic import ListView, CreateView
from django.contrib.messages.views import SuccessMessageMixin
from .forms import CreatePostForm
...
...
class CreatePostView[SuccessMessageMixin, CreateView]:
template_name = 'posts/create-post.html'
form_class = CreatePostForm
success_message = 'Crate Post successfully!'
Và templates:
...
{% if messages %}
{% for message in messages %}
{{ message }}
{% endfor %}
{% endif %}
List Posts
Create Posts
...
{% extends "layouts/layout.html" %}
{% block title %}
Create Post | {{ block.super }}
{% endblock title %}
{% block content %}
Create Posts
{% csrf_token %}
Name* :
Content* :
Create Post
{% endblock content %}
Thêm hàm get_absolute_url
ở model để trở lại trang
list posts sau khi tạo nhé:
# posts/models.py
...
class Post[models.Model]:
...
...
def __unicode__[self]:
return self.content
def get_absolute_url[self]:
return reverse['posts:list-posts', kwargs={}]
4.3 Update Post
Để update bài Post đã tạo, chúng ta lại bắt đầu từ views.py
# posts/views.py
...
from django.views.generic import ListView, CreateView, UpdateView
from django.core.urlresolvers import reverse
...
class UpdatePostView[SuccessMessageMixin, UpdateView]:
template_name = 'posts/edit-post.html'
model = Post
fields = ['name', 'content',]
success_message = 'Update Post successfully!'
def get_success_url[self]:
return reverse['posts:list-posts', kwargs={}]
urls:
# posts/urls.py
...
from posts.views import [
ListPostView,
CreatePostView,
UpdatePostView,
]
urlpatterns = [
url[r'^list-posts/$', ListPostView.as_view[], name='list-posts'],
url[r'^create-post/$', CreatePostView.as_view[], name='create-post'],
url[r'^update-post/[?P[-\w]+]$', UpdatePostView.as_view[], name='update-post'],
]
templates:
{% extends "layouts/layout.html" %}
{% block title %}
Edit Post | {{ block.super }}
{% endblock title %}
{% block content %}
Edit Posts
{% csrf_token %}
Name* :
Content* :
{{object.content}}
Update Post
{% endblock content %}
Sửa thêm nút edit vào trang list posts:
...
{% for post in posts %}
{{post.name}}
Post at {{post.timestamp}}
{{post.content}}
Edit
{% endfor %}
...
4.4 Delete Post
Đối với chức năng xóa bài post, ở ví dụ này mình sẽ sử dụng Base View:
# posts/views.py
...
def delete_post[request, pk]:
post = Post.objects.filter[id=pk]
post.delete[]
context = {
"messages": "Delete Post successfully",
'posts': Post.objects.all[]
}
return render[request, 'posts/list-posts.html', context]
urls:
# posts/urls.py
...
from posts import views
...
urlpatterns = [
url[r'^list-posts/$', ListPostView.as_view[], name='list-posts'],
url[r'^create-post/$', CreatePostView.as_view[], name='create-post'],
url[r'^update-post/[?P[-\w]+]$', UpdatePostView.as_view[], name='update-post'],
url[r'^delete-post/[?P[-\w]+]$', views.delete_post, name='delete-post'],
]
Thêm nút xóa:
{% for post in posts %}
{{post.name}}
Post at {{post.timestamp}}
{{post.content}}
Edit
Delete
{% endfor %}
Hiển thị thông báo xóa thành công ở layout:
{% if messages %}
{% for message in messages %}
{{ message }}
{% endfor %}
{% endif %}
{% if success %}
{{success}}
{% endif %}
List Posts
Create Posts
5. DEMO
Create Post
Khi success
Edit post
Success
Delete post
Success
6. End
Như vậy là chúng ta đã hoàn thành chủ đề CRUD cơ bản với Python sử dụng Django và MySql rồi.
Hy vọng bài viết này sẽ một phần nào đó giúp các bạn hiểu hơn về python.
Nếu thấy hay, hãy upvote, share để được đẹp trai và xinh gái hơn.