Hướng dẫn lập trình CRUD Restful API với Django Python dễ dàng.
Ứng dụng các công nghệ để lập trình web với python:
- Python
- Django REST Framework
- SQL lite
- Visual Studio Code
- Python extension by Microsoft
Tại sao dùng Django REST Framework?
Django REST Framework (REST Framework) cung cấp 4 tính năng:
- Browsable API
- Auth Support
- Throttling: giới hạn quyền truy cập của người dùng.
- Serializers: chuyển đổi model thành json object.
Nếu bạn là người bắt đầu với lập trình web python thì đừng bỏ lỡ bài viết:
Django Project Setup
Xem thêm:
Tạo thư mục django-employee và kích hoạt virtualenv:
$ mkdir django-employee
$ cd django-employee
$ python -m venv env
Nhấn Ctrl + Shift + P chọn Python: Selection interpreter và chọn bản python bạn muốn dùng. Chi tiết hơn bạn tham khảo bài viết này
Lúc này sẽ xuất hiện (env) ở command line.
(env)$ pip install django
(env)$ django-admin startproject myemployee
Cấu trúc dự án lúc này:
└── myemployee
├── manage.py
└── myemployee
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
Cấu hình cho Django REST Framework
Chúng ta sẽ tạo app employee.
(env)$ cd myemployee
(env)$ python manage.py startapp employee
(env)$ pip install djangorestframework
Bây giờ chúng ta cấu hình cho Django project dùng REST Framework.
Đầu tiên, bạn thêm employee
và rest_framework
vào mục INSTALLED_APPS
trong myemployee/myemployee/settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'employee',
'rest_framework'
]
Tiếp theo, định nghĩa settings cho REST Framework, thêm code bên dưới vào file settings.py :
REST_FRAMEWORK =
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [],
'TEST_REQUEST_DEFAULT_FORMAT': 'json'
Điều này sẽ không giới hạn việc truy cập tới API và thiết lập mặc định trả về JSON cho tất cả các request.
Do mình develop ở localhost nên không cần đòi hỏi giới hạn truy cập. Nhưng nếu ở production thì phải giới hạn việc truy cập tới endpoints. Xem thêm ở đây.
Cấu trúc project hiện tại thế này:
└── myemployee
├── manage.py
├── employee
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── myemployee
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
Database mình sẽ dùng mặc định là SQLite của Django đã hỗ trợ nên không cấu hình phần này.
Tiếp theo, chúng ta sẽ định nghĩa model Employee trong file django-employee/myemployee/employee/models.py:
from django.db import models
class Employee(models.Model):
name = models.CharField(max_length=255)
age = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def get_info(self):
return 'Name: ' + self.name + ' age: ' + self.age
def __repr__(self):
return self.name + ' is added.'
Thực thi migration cho database:
(env)$ python manage.py makemigrations
(env)$ python manage.py migrate
Bạn hãy check database db.sqlite3 sẽ thấy thay đổi.
Serializers
Trước khi tạo API, chúng ta sẽ định nghĩa serializer cho model Employee. Hiểu đơn giản serializers là cách chúng ánh xạ các field trong class model (chuyển từ class model sang json và ngược lại).
Thêm code django-employee/myemployee/employee/serializers.py:
from rest_framework import serializers
from .models import Employee
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = ('name', 'age', 'created_at', 'updated_at')
ModelSerializer
sẽ ánh xạ tương ứng các field cho model Employee.
Bây giờ là phần quan trọng, tiến hành làm RESTful API nào !
Endpoint |
HTTP Method |
CRUD Method |
Result |
---|
employees |
GET |
READ |
Get all employee |
employees/:id |
GET |
READ |
Get a single employee |
employees |
POST |
CREATE |
Add a single employee |
employees/:id |
PUT |
UPDATE |
Update a single employee |
employees/:id |
DELETE |
DELETE |
Delete a single employee |
Trước khi implement API routes chúng ta sẽ định nghĩa skeleton để return empty và map chúng với URL tương thích trong file django-employee/myemployee/employee/views.py:
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Employee
from .serializers import EmployeeSerializer
@api_view(['GET', 'DELETE', 'PUT'])
def get_delete_update_employee(request, pk):
try:
employee = Employee.objects.get(pk=pk)
except Employee.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
# get details of a single employee
if request.method == 'GET':
return Response()
# delete a single employee
elif request.method == 'DELETE':
return Response()
# update details of a single employee
elif request.method == 'PUT':
return Response()
@api_view(['GET', 'POST'])
def get_post_employee(request):
# get all employee
if request.method == 'GET':
return Response()
# insert a new record for a employee
elif request.method == 'POST':
return Response()
Tạo URLs đúng với views trong file django-employee/myemployee/employee/urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(
r'^api/employee/(?P<pk>[0-9]+)$',
views.get_delete_update_employee,
name='get_delete_update_employee'
),
url(
r'^api/employee/$',
views.get_post_employee,
name='get_post_employee'
)
]
Đồng thời update file django-employee/myemployee/myemployee/urls.py:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^', include('employee.urls')),
url(
r'^api-auth/',
include('rest_framework.urls', namespace='rest_framework')
),
url(r'^admin/', admin.site.urls),
]
Browsable API
Tất cả các route đã map với function, chúng ta sẽ test thử REST Framework’s Browsable API và xem chúng làm việc thế nào nha.
Tại Command line gõ:
(env)$ python manage.py runserver
Truy cập: http://localhost:8000/api/employee
Bạn sẽ thấy giao diện HTML với API response.
Bây giờ chúng ta sẽ bổ sung cho đủ các hàm trong file views.
Routes
GET ALL
Update code ở file employee/views.
@api_view(['GET', 'POST'])
def get_post_employee(request):
# get all employee
if request.method == 'GET':
employees = Employee.objects.all()
serializer = EmployeeSerializer(employees, many=True)
return Response(serializer.data)
# insert a new record for a employee
elif request.method == 'POST':
return Response()
POST
Inserting employee cũng có 2 trường hợp: hợp lệ và không hợp lệ.
@api_view(['GET', 'POST'])
def get_post_employee(request):
# get all employee
if request.method == 'GET':
employees = Employee.objects.all()
serializer = EmployeeSerializer(employees, many=True)
return Response(serializer.data)
# insert a new record for a employee
if request.method == 'POST':
data =
'name': request.data.get('name'),
'age': int(request.data.get('age'))
serializer = EmployeeSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Tại đây, chúng sẽ chèn dòng mới bởi serializing và xác nhận field hợp lệ trước khi chèn vào database.
Truy cập: http://localhost:8000/api/employee/ và thêm data mẫu bên dưới.
"name": "Lam",
"age": 4
GET Single
Get employee có 2 trường hợp:
- Hợp lệ: employee tồn tại
- Không hợp lệ: employee không tồn tại
@api_view(['GET', 'UPDATE', 'DELETE'])
def get_delete_update_employee(request, pk):
try:
employee = Employee.objects.get(pk=pk)
except Employee.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
# get details of a single employee
if request.method == 'GET':
serializer = EmployeeSerializer(employee)
return Response(serializer.data)
PUT
Method PUT để cập nhật 1 employee
@api_view(['GET', 'DELETE', 'PUT'])
def get_delete_update_employee(request, pk):
try:
employee = Employee.objects.get(pk=pk)
except Employee.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
# get details of a single employee
if request.method == 'GET':
serializer = EmployeeSerializer(employee)
return Response(serializer.data)
# update details of a single employee
if request.method == 'PUT':
serializer = EmployeeSerializer(employee, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_204_NO_CONTENT)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# delete a single employee
elif request.method == 'DELETE':
return Response()
DELETE
To delete a single record, an ID is required:
@api_view(['GET', 'DELETE', 'PUT'])
def get_delete_update_employee(request, pk):
try:
employee = Employee.objects.get(pk=pk)
except Employee.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
# get details of a single employee
if request.method == 'GET':
serializer = EmployeeSerializer(employee)
return Response(serializer.data)
# update details of a single employee
if request.method == 'PUT':
serializer = EmployeeSerializer(employee, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_204_NO_CONTENT)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# delete a single employee
if request.method == 'DELETE':
employee.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Xong! Bạn có thể thử với các Restful API như mục trên, danh sách employee api click đây.
Mình đã Hướng dẫn lập trình web Python CRUD Restful API với Django Python qua dự án Employee dễ dàng. Các bạn có thắc gì cứ bình luận bên dưới nhé!
Download source code Python web:
Employee project
Học hành, Lập trình
Lập trình, Python