使用Django View视图开发REST 接口
model
python
from django.db import models
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.contrib.auth.models import AbstractUser
def validate_read(value):
if value <= 0:
raise ValidationError('阅读量必须是一个正整数。')
def validate_comment(value):
if value <= 0:
raise ValidationError('评论量必须是一个正整数。')
class BookInfo(models.Model):
title = models.CharField(max_length=30, verbose_name='书籍名')
pub_date = models.DateField(verbose_name='出版日期')
read = models.PositiveIntegerField(verbose_name='阅读量', validators=[validate_read])
comment = models.PositiveIntegerField(verbose_name='评论量',
blank=True, null=True, validators=[validate_comment])
class Meta:
db_table = 'bookinfo'
urls
python
urlpatterns = [
# path('admin/', admin.site.urls),
path('books/', views.BookListView.as_view()),
path('books/<int:pk>/', views.BookDetailView.as_view())
]
views
python
from django.shortcuts import render, HttpResponse
"""
基于 Django View 开发REST接口
GET /goods 获取所有商品
POST /goods 增加商品
GET /goods/1 获取编号为1的商品
PUT /goods/1 修改编号为1的商品
DELETE /goods/1 删除编号为1的商品
响应数据 JSON
"""
from django.views import View
from django.http import JsonResponse, HttpResponse
import json
from app.models import BookInfo
class BookListView(View):
# 查询所有
def get(self, request):
# 1.查询所有,queryset类型
books = BookInfo.objects.all()
# 2.遍历查询集,将模型对象变成字典
book_list = []
for book in books:
book_dict = {
'title': book.title,
'pub_date': book.pub_date,
'read': book.read,
'comment': book.comment if book.comment else ''
}
book_list.append(book_dict)
# 3。响应给前端
# 参数safe=False是必要的,因为book_list是一个非字典对象,
# 而JsonResponse默认只接受字典对象(出于安全考虑)。
# 将safe设置为False可以允许传递非字典对象,如列表。
return JsonResponse(book_list, safe=False)
# 新增
def post(self, request):
# 获取前端请求体(JSON)
book_dict_bytes = request.body
print('bytes类型:', book_dict_bytes)
# 把 bytes 类型的 json数据,转换为 json str
book_dict_str = book_dict_bytes.decode()
print('str类型', book_dict_str)
# json.loads():将一个 JSON 格式的字符串转换成 Python 的数据类型
# (通常是字典或列表,但也可能是字符串、数字、布尔值等)。
data_dict = json.loads(book_dict_str)
print('JSON格式的字符串转换成 Python 的数据类型:', data_dict)
# 新增
book = BookInfo.objects.create(**data_dict)
# 准备返回数据:JsonResponse 用于返回字典或列表
response_data = {
'title': book.title,
'pub_date': book.pub_date,
'read': book.read,
'comment': book.comment if book.comment else ''
}
return JsonResponse(response_data, status=201)
class BookDetailView(View):
# 查询指定
def get(self, request, pk):
try:
book = BookInfo.objects.get(pk=pk)
book_dict = {
'title': book.title,
'pub_date': book.pub_date,
'read': book.read,
'comment': book.comment if book.comment else ''
}
except Exception as e:
return JsonResponse({'message': '没有此图书'}, status=404)
return JsonResponse(book_dict)
# 修改指定
def put(self, request, pk):
try:
book = BookInfo.objects.get(pk=pk)
except BookInfo.DoesNotExist:
return JsonResponse({'message': '没有此图书'}, status=404)
# 获取前端请求体(JSON)
book_dict_bytes = request.body
# 把 bytes 类型的 json数据,转换为 json str
book_dict_str = book_dict_bytes.decode()
# json.loads():将一个 JSON 格式的字符串转换成 Python 的数据类型
# (通常是字典或列表,但也可能是字符串、数字、布尔值等)。
data_dict = json.loads(book_dict_str)
print('data_dict', data_dict)
# 更新对象的属性(只更新允许的字段)
allowed_fields = {'title', 'pub_date', 'read', 'comment'}
# 从接收到的data_dict里处理需要修改的数据
# 对一个字典调用 items() 方法时,它会返回一个可迭代的视图对象,
# 该对象包含了字典中的键值对(key-value pairs)。
# 每个键值对都以一个元组(tuple)的形式表示,
# 元组中第一个元素是键,第二个元素是与该键相关联的值。
for field, value in data_dict.items():
# hasattr(book, field): 这个函数检查 book 对象是否有名为 field 的属性, 返回布尔值
if field in allowed_fields and hasattr(book, field):
# setattr(book, field, value):这个函数用于动态地设置对象的属性。
# 在这里,它将 book 对象的 field 属性设置为 value。
setattr(book, field, value)
book.save()
# 准备返回数据:JsonResponse 用于返回字典或列表
response_data = {
'title': book.title,
'pub_date': book.pub_date,
'read': book.read,
'comment': book.comment if book.comment else ''
}
return JsonResponse(response_data, status=200)
# 删除指定
def delete(self, request, pk):
try:
book = BookInfo.objects.get(pk=pk)
except BookInfo.DoesNotExist:
return JsonResponse({'message': '没有此图书'}, status=404)
book.delete()
return JsonResponse({'message': '删除成功'}, status=200)
getattr()
getattr()
是 Python 中的一个内置函数,它用于获取对象的属性值。如果指定的属性存在,getattr()
会返回其值;如果不存在,则可以返回一个默认值(如果提供了的话),或者抛出一个 AttributeError
异常(如果没有提供默认值)。
getattr()
函数的基本语法如下:
python
getattr(object, name[, default])
-
object
:要获取属性的对象。 -
name
:要获取的属性的名称(作为字符串)。 -
default
:(可选)如果属性不存在,则返回的值。如果不提供此参数,并且属性不存在,则会抛出AttributeError
。
hasattr()
hasattr()
是 Python 中的一个内置函数,用于检查对象是否具有指定的属性。它接受两个参数:一个是要检查的对象,另一个是属性名的字符串。如果对象具有该属性,hasattr()
返回 True
;如果不具有,则返回 False
。
python
hasattr(object, name)
-
object
:要获取属性的对象。 -
name
:要获取的属性的名称(作为字符串)。
setattr()
setattr()
是 Python 的内置函数之一,其用途是设置对象的属性值。该函数接受三个参数:对象本身、属性名(需为字符串形式)以及要设置的新属性值。若指定的属性在对象中已存在,setattr()
会更新其值;若不存在,则会创建该属性并赋值。
以下是 setattr()
的基本语法:
python
setattr(object, name, value)
object
:代表要设置属性的对象。name
:表示要设置的属性名,需以字符串形式提供。value
:指定属性的新值。