用户注册
user/views
class UserApiView(APIView):
#注册功能实现
def post(self,request):
# 反序列化,json变对象
user_data_serializer=UserSerializer(data=request.data)
user_data_serializer.is_valid(raise_exception=True)
user_data=user_data_serializer.save()
#返回之前需要序列化
user_ser=UserSerializer(instance=user_data)
return ResponseMessage.UserResponse.success(user_ser.data)
user_data = user_data_serializer.save()
这个方法的作用是将序列化器的数据保存到数据库中。我们之前的写法是: user_data=User.objects.create(**user_data_serializer.data),很明显使用save更加简洁
user/serializers
import datetime
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from apps_shop.user.models import User
from utils.password_encode import get_md5
class UserSerializer(serializers.ModelSerializer):
# email作为用户名进行登录,这里我们需要做一个唯一性的验证
email = serializers.EmailField(
required=True,
allow_blank=False,
validators=[UniqueValidator(queryset=User.objects, message="用户已经存在了")]
)
# password = serializers.CharField(write_only=True)
password = serializers.CharField()
birthday = serializers.DateTimeField("%Y-%m-%d %H:%M:%S")
create_time = serializers.DateTimeField("%Y-%m-%d %H:%M:%S",required=False)
# create方法会被自动调用,这里可以做一些数据的验证或者是存储之前数据的加工
def create(self, validated_data):
print("create方法被调用了")
print(validated_data)
validated_data["password"] = get_md5(validated_data["password"])
validated_data["create_time"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
result = User.objects.create(**validated_data)
return result
class Meta:
model = User
fields = "__all__"
我们对数据进行加工之后直接赋值,就可以保证密码不被泄露,因为存储和返回的都是加密过后的
md5
对用户密码进行加密
password = serializers.CharField(write_only=True) 只写属性,表示不能读,我们返回也就没有密码,防止被拦截密码
.datetime.now().strftime
生成当前时间并且格式化时间
user/urls
from django.urls import path
from .views import UserApiView
urlpatterns = [
# 注册
path('',UserApiView.as_view()),
]
根目录 utils/ResponseMessage
# 用户的响应全部都是4开头的
class UserResponse():
@staticmethod
def success(data):
result = {"status":4000,"data":data}
return JsonResponse(result,safe=False)
@staticmethod
def failed(data):
result = {"status": 4001, "data": data}
return JsonResponse(result, safe=False)
@staticmethod
def other(data):
result = {"status": 4002, "data": data}
return JsonResponse(result, safe=False)
数据库
alter table user modify create_time datetime null default CURRENT_TIMESTAMP
用户信息获取
user/views
# Create your views here.
class UserApiView(APIView):
.....
#获取用户信息
def get(self, request):
email = request.GET.get("email")
try:
user_data = User.objects.get(email=email)
user_ser = UserSerializer(user_data)
return ResponseMessage.UserResponse.success(user_ser.data)
except Exception as e:
print(e)
return ResponseMessage.UserResponse.failed("用户信息获取失败")
try...except
try
后面的代码块是你要尝试执行的代码。如果在这个代码块中发生了异常,Python 将跳过剩余的代码并进入与异常类型匹配的except
块,从而进行异常处理
try: # 可能引发异常的代码块 except ExceptionType1: # 处理 ExceptionType1 类型的异常 except ExceptionType2: # 处理 ExceptionType2 类型的异常 else: # 如果没有发生任何异常,则执行该块 finally: # 无论是否发生异常,都会执行该块
订单
创建订单
数据库
create table order_goods(
id int not null auto_increment,
trade_no varchar(255) collate utf8mb4_general_ci,
sku_id varchar(255) collate utf8mb4_general_ci,
goods_num int,
create_time datetime default CURRENT_TIMESTAMP,
primary key(id)
)engine=INNODB charset=utf8mb4 collate=utf8mb4_general_ci;
create table `order`(
id int not null auto_increment,
email varchar(255) collate utf8mb4_general_ci,
order_amount decimal(10,2),
address_id int,
pay_status varchar(155),
pay_time datetime default CURRENT_TIMESTAMP,
ali_trade_no varchar(255) collate utf8mb4_general_ci,
is_delete int UNSIGNED default 0,
create_time datetime default CURRENT_TIMESTAMP,
update_time datetime default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
primary key(id)
)engine=INNODB charset=utf8mb4 collate=utf8mb4_general_ci;
collate
order/models
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models
class Order(models.Model):
email = models.CharField(max_length=255, blank=True, null=True)
trade_no = models.CharField(max_length=155, blank=True, null=True)
order_amount = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
address_id = models.IntegerField(blank=True, null=True)
pay_status = models.CharField(max_length=155, blank=True, null=True)
pay_time = models.DateTimeField(blank=True, null=True)
ali_trade_no = models.CharField(max_length=255, blank=True, null=True)
is_delete = models.PositiveIntegerField(blank=True, null=True)
create_time = models.DateTimeField(blank=True, null=True)
# update_time = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'order'
class OrderGoods(models.Model):
trade_no = models.CharField(max_length=255, blank=True, null=True)
sku_id = models.CharField(max_length=255, blank=True, null=True)
goods_num = models.IntegerField(blank=True, null=True)
# create_time = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'order_goods'
order/views
class OrderGoodsGenericAPIView(GenericAPIView):
queryset = OrderGoods.objects
serializer_class = OrderGoodsSerializer
def post(self, request):
ser = self.get_serializer(data=request.data)
ser.is_valid()
ser.save()
return JsonResponse("ok",safe=False)
queryset = OrderGoods.objects
该视图类提供了一个
queryset
属性,它指定了要在视图中使用的查询集。在这里,queryset
被设置为OrderGoods.objects
,意味着你将使用OrderGoods
模型的查询集作为数据源,就是这里我可以直接获取到整个数据集
order/Serializer
from rest_framework import serializers
from apps_shop.order.models import OrderGoods
class OrderGoodsSerializer(serializers.ModelSerializer):
class Meta:
model = OrderGoods
fields = "__all__"
order/urls
path("goods/",OrderGoodsGenericAPIView.as_view()),
获取订单接口
order/views
lookup_field = "trade_no"
def get(self, request,trade_no):
# 这一行代码就实现了数据库里所有数据的查询
# return JsonResponse(self.get_serializer(instance=self.get_queryset(),many=True).data,safe=False)
# ser = self.get_serializer(instance=self.get_object(),many=False)
ser = self.get_serializer(instance=self.get_object(),many=True)
return JsonResponse(ser.data,safe=False)
ser = self.get_serializer(instance=self.get_object(),many=False)
queryset = OrderGoods.objects
serializer_class = OrderGoodsSerializer
order/urls
from django.urls import path, re_path
from .views import OrderGoodsGenericAPIView
urlpatterns = [
path("goods/",OrderGoodsGenericAPIView.as_view()),
re_path("goods/(?P<trade_no>.*)",OrderGoodsGenericAPIView.as_view()),
]
re_path("goods/(?P<trade_no>.*)
收货地址接口
address/models
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models
class UserAddress(models.Model):
id = models.IntegerField(primary_key=True)
email = models.CharField(max_length=255, blank=True, null=True)
signer_name = models.CharField(max_length=255, blank=True, null=True)
telphone = models.CharField(max_length=255, blank=True, null=True)
signer_address = models.CharField(max_length=255, blank=True, null=True)
district = models.CharField(max_length=255, blank=True, null=True)
default = models.IntegerField(blank=True, null=True)
create_time = models.DateTimeField()
class Meta:
managed = False
db_table = 'user_address'
问题
RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to localhost:8000/user/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.
解决:请求路径要以斜杠结尾
TypeError: django.db.models.query.QuerySet.create() argument after ** must be a mapping, not UserSerializer
解决:忘记取data
AssertionError: 'OrderGoodsGenericAPIView' should either include a
queryset
attribute, or override theget_queryset()
method.
解决:在视图类中设置 queryset
属性,并将其指定为合适的查询集对象。例如:serializer_class = OrderGoodsSerializer
apps_shop.order.models.OrderGoods.MultipleObjectsReturned: get() returned more than one OrderGoods -- it returned 3!
未知:这里报错是因为返回了多个数据,但是我们明确写了many=true,但是还是报错