Django REST Framework中的Serializer relations

834 阅读2分钟

官方文档原文


Relational fields are used to represent model relationships. They can be applied to ForeignKey, ManyToManyField and OneToOneField relationships, as well as to reverse relationships, and custom relationships such as GenericForeignKey.

Note: The relational fields are declared in relations.py, but by convention you should import them from the serializers module, using from rest_framework import serializers and refer to fields as serializers.<FieldName>.

1、序列化类中的关系字段用于表示模型中的关系 包含一对一,一对多,多对多 2、Django REST Framework中的关系字段在relations.py中声明 通过from rest_framework import serializers导入 同时设置相关字段为serializers.

实例:

models.py

class Member(AbstractBaseUser):
    USERNAME_FIELD = 'mobile_no'
    individual_position = models.CharField(verbose_name='Individual position', max_length=64, null=True, blank=True)
    username = models.CharField(verbose_name='username', max_length=64, null=True, blank=True)
    password = models.CharField(verbose_name='password', max_length=128)

class Card(models.Model):

    card_no = models.CharField(verbose_name=' Member card number Member', max_length=64, null=True, blank=True, unique=True)
    member = models.ForeignKey(verbose_name='Member', to='Member', related_name='cards', on_delete=models.CASCADE, null=True, blank=True)
    printed_name = models.CharField(verbose_name='The name of the member card', max_length=64, null=True, blank=True)
    membership_type_code = models.CharField(verbose_name='Member type code', max_length=64, null=True, blank=True)
    membership_status_code = models.CharField(verbose_name='Member status code', max_length=64, null=True, blank=True)
    
views.py

from accounts.serializers import CardSerializer,MemberSerializer
from accounts.models import Card, Member

class CreateCardViewSet(viewsets.ModelViewSet):
    serializer_class = CardSerializer
    queryset = Card.objects.all()

class CreateMemberViewSet(viewsets.ModelViewSet):
    serializer_class = MemberSerializer
    queryset = Member.objects.all()
    
serializers.py

from accounts.models import Comment, Ip, MyUsers, Admire, Card, Member


class MemberSerializer(serializers.ModelSerializer):
    cards = serializers.PrimaryKeyRelatedField(many=True, queryset=Card.objects.all()) # read_only=True
    class Meta:
        model = Member
        fields = '__all__'


class CardSerializer(serializers.ModelSerializer):
    # member = serializers.PrimaryKeyRelatedField(read_only=True)
    member = MemberSerializer(required=False)
    class Meta:
        model = Card

urls.py
router.register(r'members', views.CreateMemberViewSet)

read_only=True:表示只读
Member和Card是一对多
cards是在Card模型中设置的related_name用于反向查找
一张卡片只能属于一个会员
设置member = MemberSerializer(required=False)可以在序列化后的json数据中显示Member中的字段的值(以列表和字典的形式)
会员可以有多张卡
设置
 cards = serializers.PrimaryKeyRelatedField(many=True, queryset=Card.objects.all()) # read_only=True
可以Member模型中的数据更新同步到Cards
many=True表示可以传递一个列表的数据,
但是问题在于这里是创建会员卡的同时创建会员,如何设置创建会员的时候创建会员卡

改为创建会员的时候创建会员卡 GET http://127.0.0.1:8000/cards/




class MemberSerializer(serializers.ModelSerializer):
    cards = serializers.PrimaryKeyRelatedField(many=True, queryset=Card.objects.all())

    class Meta:
        model = Member
        fields = '__all__'
        depth = 2


class CardSerializer(serializers.ModelSerializer):

    # member = serializers.PrimaryKeyRelatedField(read_only=True) # read_only=True
    member = MemberSerializer(required=False)

    class Meta:
        model = Card
        fields = '__all__'

结果:

POST http://127.0.0.1:8000/members/
{
    "id": 37,
    "cards": [
        4
    ],
    "last_login": null,
    "individual_position": "student",
    "salutation": "Mr",
    "name": "Li",
    "nric": null,
    "passport": null,
    "email": "1119181@qq.com",
    "gender": null,
    "dob": null,
    "nationality": null,
    "block": null,
    "level": null,
    "unit": null,
    "street": null,
    "building": null,
    "postal_code": null,
    "country": null,
    "address1": null,
    "address2": null,
    "address3": null,
    "contact_no": null,
    "mobile_no": "187878787383",
    "fax_no": null,
    "referrer_code": null,
    "facebook_id": null,
    "facebook_name": null,
    "facebook_photo_link": null,
    "facebook_token": null,
    "facebook_token_expiry": null,
    "full_photo_name": null,
    "base64_photo_string": null,
    "photo_link": null,
    "race_code": null,
    "notify_post": null,
    "notify_sms": null,
    "first_name": null,
    "last_name": null,
    "join_date": "2018-06-14T06:16:37.176830Z",
    "username": null,
    "password": "sky",
    "membership": null,
    "role": null,
    "interestGroups": []
}
上面创建会员同时创建会员卡
GET http://127.0.0.1:8000/cards/4/
查看会员卡信息
{
    "id": 4,
    "member": {
        "id": 37,
        "cards": [
            4
        ],
        "last_login": null,
        "individual_position": "student",
        "salutation": "Mr",
        "name": "Li",
        "nric": null,
        "passport": null,
        "email": "1119181@qq.com",
        "gender": null,
        "dob": null,
        "nationality": null,
        "block": null,
        "level": null,
        "unit": null,
        "street": null,
        "building": null,
        "postal_code": null,
        "country": null,
        "address1": null,
        "address2": null,
        "address3": null,
        "contact_no": null,
        "mobile_no": "187878787383",
        "fax_no": null,
        "referrer_code": null,
        "facebook_id": null,
        "facebook_name": null,
        "facebook_photo_link": null,
        "facebook_token": null,
        "facebook_token_expiry": null,
        "full_photo_name": null,
        "base64_photo_string": null,
        "photo_link": null,
        "race_code": null,
        "notify_post": null,
        "notify_sms": null,
        "first_name": null,
        "last_name": null,
        "join_date": "2018-06-14T06:16:37.176830Z",
        "username": null,
        "password": "sky",
        "membership": null,
        "role": null,
        "interestGroups": []
    },
    "card_no": null,
    "printed_name": null,
    "membership_type_code": null,
    "membership_status_code": null,
    "membership_photo": null,
    "issue_date": null,
    "effective_date": null,
    "expiry_date": null,
    "printed": null,
    "printed_date": null,
    "renewed_date": null,
    "tmp_effective_date": null,
    "tmp_expiry_date": null,
    "tmp_membership_status_code": null,
    "points_bal": null,
    "total_points_bal": null,
    "holding_points": null,
    "remarks": null,
    "membership_discount": null,
    "tier_code": null,
    "tier_anniversary_start_date": null,
    "tier_anniversary_end_date": null,
    "loyalty_message": null,
    "dollar_to_points_ratio": null,
    "is_supplementary": null,
    "is_burn_supplementary": null,
    "relation_id": null,
    "primary_card_no": null,
    "primary_relation_id": null,
    "primary_card_expiry_date": null,
    "primary_card_effective_date": null,
    "pts_holding_days": null,
    "current_net_spent": null,
    "pass_code": null,
    "stored_value_balance": null,
    "currency": null,
    "last_visited_date": null,
    "last_visited_outlet": null,
    "points_to_next_tier": null,
    "nett_to_next_tier": null,
    "lucky_draw_conversion_pts_usage_type": null,
    "lucky_draw_conversion_rate": null,
    "spent_quota_increasement": null,
    "spent_quota_increasement_expired_on": null,
    "pickup_date": null,
    "pickup_by": null,
    "current_rcnett_spent": null,
    "cmc_earned_points": null,
    "crc_earned_points": null,
    "current_tier_nett": null,
    "current_tier_amt": null,
    "bring_fwd_tier_nett": null,
    "bring_fwd_tier_amt": null,
    "bring_fwd_tier_expiry": null,
    "bring_fwd_tier_start_date": null,
    "extended_tier_anniversary_end_date": null
}