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 siteposts/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/

Related article