Series Django (P2): Bắt đầu với app đầu tiên với django-rest-framework
Như trong phần trước, các bác đã cài đặt xong django và bước đầu chạy được local server. Thì ở phần này mình sẽ đi tạo app mới để bắt đầu với chức năng của bài post.
Tạo post app
Mọi app mà các bác viết bằng Django đều là một python package
. Một app có thể ở bất cứ đâu trong một project. Nhưng mình sẽ tạo nó ở cạnh manage.py, để sau này ta có thể import nó như một top-level module.
Giờ các bác tạo post app cùng dir với manage.py
với lệnh
$ python3 manage.py startapp posts
Và cấu trúc thư mục posts
như sau:
posts/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
Giải thích thêm về các thành phần trong posts app
- init.py: Để chỉ cho python rằng thư mục này là một package.
- admin.py: File config trong trang admin của app
- models.py: file model, chứa mọi thứ liên quan đến dữ liệu
- tests.py: file unit test
- views.py: file request/responsive, chứa logic, các truy vấn dữ liệu từ model
(nếu các hay sử dụng mô hình MVC thì thằng Django này cũng sử dụng mô hình khá giống là MVT trong đo M-model của django tương ứng, V-view lại tương ứng với thằng controller ở MVC còn T-template lại tương ứng với view ở MVC)
Để test đơn giản của app, mình sẽ tạo 1 view đơn giản sau. Với file views.py
của posts
, các bác thêm giúp mình đoạn sau:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello.")
Để gọi views trên, phải gán nó với 1 URL và ta sẽ tạo 1 file urls.py
- URLconf
posts/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
urls.py
views.py
và nội dung file
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
Để gọi nó ra, mình sẽ gọi nó ở root URLconf(socialapp/urls.py)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('posts/', include('posts.urls')),
path('admin/', admin.site.urls),
]
include() cho phép sử dụng các URLconf của các app con từ root URLconf.
Chạy thử http://127.0.0.1:8000/posts/ server xem kết quả sau khi chạy lệnh
$ python3 manage.py runserver
Sau khi tạo được 1 app hoàn chỉnh, mình sẽ config Django REST framework lên. Django REST framework rất mạnh mẽ và linh hoạt trong việc xây dựng Web APIs.
Để sử dụng Django REST framework, mình install nó
$ pip3 install djangorestframework
và thêm nó và post app vào INSTALLED_APPS
trong settings.py
INSTALLED_APPS = (
...
'rest_framework',
posts,
)
Sau khi config xong, tạo thư mục api trong posts app. Đây là nơi mình sẽ thao tác với Django REST framework.
Nhưng trước tiên mình sẽ tạo model của thằng posts. Trong posts/models.py, tạo model post:
from django.db import models
class Post(models.Model):
content = models.TextField()
slug = models.SlugField(unique=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __str__(self):
return self.content
class Meta:
ordering = ["timestamp", "updated"]
và chạy migrate:
$ python3 manage.py makemigrations
$ python3 manage.py migrate
Bây giờ, mình sẽ quay trở lại với thư mục api.
Trong đó, mình tạo views và import Generic views
(nó cung cấp GenericAPIView với các Concrete View Classes theo CRUD - CreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView).
Trong posts/api/views.py
from rest_framework.generics import ListAPIView
from posts.models import Post
class PostListAPIView(ListAPIView):
queryset = Post.objects.all()
sau khi tạo views.py xong, mình sẽ tạo thêm urls.py để import PostListAPIView
mình vừa tạo ở trên và gán url cho nó.
Trong posts/api/urls.py
from django.conf.urls import url
from .views import PostListAPIView
urlpatterns = [
url(r'^$', PostListAPIView.as_view(), name='list'),
]
Sau đó là add URL trên vào url của project.
Tại socialapp/urls.py thêm dòng sau:
from django.conf.urls import include, url
urlpatterns = [
url(r'^api/posts/', include(('posts.api.urls', 'posts-api'), namespace="posts-api")),
]
Lúc này ta có thể lấy được tất cả bài posts nhưng với dạng dữ liệu phức tạp(queryset). Để dịch sang dạng JSON
hoặc XML
ta cần Serializers
. Serializers trong REST này rất giống form/ModelForm
trong Django.
Trước tiên mình sẽ tạo serializers.py
trong posts/api/ và import serializers. Đồng thời, trong serializers.py cũng tạo PostSerializer
có các metadata, đây là các thông tin lưu trữ về các thiết lập của model.
file post/api/serializers.py
from rest_framework.serializers import ModelSerializer
from posts.models import Post
class PostSerializer(ModelSerializer):
class Meta:
model = Post
fields = '__all__'
Sau khi khai báo xong, thì runserver thôi,
$ python3 manage.py runserver
và truy cập vào http://127.0.0.1:8000/api/posts/ trên trình duyệt để get được list posts.
Kết quả thu được:
Để có dữ liệu cho sinh động thì mình cho thằng posts app này đươcj quản lý với superuser. Nhưng trước tiên, phải tạo superuser đã.
$ python3 manage.py createsuperuser
Nhập username and password. Sau đó đăng nhập vào http://127.0.0.1:8000/admin/ bằng superuser vừa tạo.
Để có thể quản lý post app, mình sẽ đăng ký admin site
ở posts/admin.py bằng đoạn code dưới:
from django.contrib import admin
from .models import Post
admin.site.register(Post)
Và bây giờ, reload lại trang admin, mình sẽ thấy được admin quản lý posts(thêm, sửa, xóa)
Mình sẽ thêm vài post và reload lại trang post list
http://127.0.0.1:8000/api/posts/
thì sẽ có
Tóm lại
Mình vừa thực hiện bước đầu với post app và thao tác cùng với Django rest framework.
Phần tiếp theo mình sẽ thực hiện CRUD với post app. Cảm ơn các bác đã theo dõi và hẹn gặp lại trong 1 ngày không xa.
Suýt quên mất, nhắn nhỏ các bạn:
Nếu có vẫn gặp vướng mắc trong khi thực hành hoặc có bất kì thắc mắc về Python
, Django
hay muốn tìm hiểu thêm các thông tin hữu ích, các bạn hãy tham gia group Django (Python) Vietnam để được các admin và thành viên support trực tiếp vấn đề mà bạn gặp phải nhé.
Suýt quên tập 2, dành cho bác nào chưa biết thì phần 1 nó ở đây:
Tài liệu tham khảo:
http://www.django-rest-framework.org/
http://www.django-rest-framework.org/api-guide/generic-views/
http://www.django-rest-framework.org/api-guide/serializers/