models
class TbGroupBookingInfo(models.Model):
product_group_booking_id = models.PositiveIntegerField()
pid = models.PositiveIntegerField()
status = models.PositiveIntegerField()
end_date = models.DateTimeField()
price_deposit = models.IntegerField()
price_online = models.IntegerField()
create_date = models.DateTimeField()
uid = models.PositiveBigIntegerField()
max_member_cnt = models.PositiveIntegerField()
real_member_cnt = models.PositiveIntegerField()
is_supplement_master = models.PositiveIntegerField()
class Meta:
managed = False
db_table = 'tb_group_booking_info'
verbose_name = '拼团团属性详情表'
app_label = 'order'
class TbGroupBookingUser(models.Model):
group_booking_info = models.ForeignKey(to=TbGroupBookingInfo, on_delete=models.DO_NOTHING,
db_constraint=False,
db_column='group_booking_info_id', related_name='booking_info')
uid = models.PositiveBigIntegerField()
pid = models.PositiveIntegerField()
status = models.PositiveIntegerField()
create_date = models.DateTimeField()
class Meta:
managed = False
db_table = 'tb_group_booking_user'
unique_together = (('group_booking_info_id', 'uid'),)
verbose_name = '拼团团成员表'
app_label = 'order'
需要注意的如下几个参数:
- ForeignKey外键关联,一般有关联关系的,都是主动更改为外键关联
- to关联的model类名,可以使用字符串,也可以使用类名,个人偏向于类名
- on_delete级联删除,一般作为测试人员,我们设置为models.DO_NOTHING,但需要知道,正确的设置应该是级联删除,但测试本来就会构造出很多垃圾数据,何况我们在测试的时候有时候就需要制造一些垃圾数据(代码问题出现垃圾数据)
- db_column数据库中的字段名,如果你觉得表的字段不容易理解,想改成更加容易理解的名称,就可以自定义model属性,使用db_column指定固定的字段名
- related_name,这个不太好解释,就是外键关联表,可以通过该字段指定的名称查询这个表里的信息。当然是可以通过model的类名直接进行查询的,但类名一般都很长,一般情况下大家都会设置related_name。另外如果通过类名查询,切记类名需要全小写
- managed表明该表是否是django迁移的表
- app_label指明该表属于数据库的schema,即哪个库。一般我们都会链接多个数据库,通过该字段指定该表在哪个库里
业务说明
TbGroupBookingInfo是拼团的团信息,TbGroupBookingUser是团的成员信息,一对多,一个团可以有多个成员,通过group_booking_info_id字段关联TbGroupBookingInfo表中的主键id
Serializer
嵌套方案
from rest_framework import serializers
from soyoung.models import *
class TbGroupBookingInfoSerializer(serializers.ModelSerializer):
class Meta:
model = TbGroupBookingInfo
fields = "__all__"
class TbGroupBookingUserSerializer(serializers.ModelSerializer):
class Meta:
model = TbGroupBookingUser
fields = "__all__"
class GroupBookingInfoSerializer(serializers.ModelSerializer):
# related_name='booking_info',不能随便命名,必须是related_name指定的名称
booking_info_bak = TbGroupBookingUserSerializer(many=True, souce='booking_info')
class Meta:
model = TbGroupBookingInfo
fields = ['pid', 'booking_info_bak']
class GroupBookingUserSerializer(serializers.ModelSerializer):
# 不需要重命名的时候可以简写,当然一般全量取名字应该在model中就已经定义好了
# group_booking_info = TbGroupBookingInfoSerializer()
# 这种写法不常用,group_booking_info外键的字段名
group = TbGroupBookingInfoSerializer(source='group_booking_info')
# 取关联表中的指定字段
group_pid = serializers.IntegerField(source='group_booking_info.pid')
group_uid = serializers.IntegerField(source='group_booking_info.uid')
class Meta:
model = TbGroupBookingUser
fields = "__all__"
这个方案,其实就是model和serializer是一一对应的关系,有一个model就会有一个serializer。然后view使用的serializer再重新进行定义。
主表查询从表信息,字段名是从表related_name指定的名称,想重命名可以通过source指定
从表查询主表信息,字段名就是自己的外键字段名称,同样可以通过source进行重命名
需要特别留意的是,主表查询从表的时候,不可以像从表查询主表的时候直接查询属性信息,只能查询表里的所有信息
model自定义
class TbGroupBookingInfo(models.Model):
product_group_booking_id = models.PositiveIntegerField()
pid = models.PositiveIntegerField()
status = models.PositiveIntegerField()
end_date = models.DateTimeField()
price_deposit = models.IntegerField()
price_online = models.IntegerField()
create_date = models.DateTimeField()
uid = models.PositiveBigIntegerField()
max_member_cnt = models.PositiveIntegerField()
real_member_cnt = models.PositiveIntegerField()
is_supplement_master = models.PositiveIntegerField()
class Meta:
managed = False
db_table = 'tb_group_booking_info'
verbose_name = '拼团团属性详情表'
app_label = 'order'
@property
def users(self):
queryset = self.booking_info.all()
return [{"uid": query.uid} for query in queryset]
个人偏向使用该方法,这样可以自定义需要输出的字段,上面嵌套的方案,fields不知道如何进行指定。
PS:view分享一下,用于测试
class TbGroupBookingUserView(APIView):
def get(self, request):
queryset = TbGroupBookingUser.objects.all()[:10]
serializer = GroupBookingUserSerializer(instance=queryset, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
class TbGroupBookingInfoView(APIView):
'''test'''
def get(self, request):
queryset = TbGroupBookingInfo.objects.all()[:10]
serializer = GroupBookingInfoSerializer(instance=queryset, many=True)
# print(serializer.data)
return Response(data=serializer.data, status=status.HTTP_200_OK)