django-rest-framework第一次使用使用常见问题

记录在第一次使用django-rest-framework框架使用时遇到的问题,为了便于理解在这里创建了Person和Grade这两个model

from django.db import models
class Person(models.Model):
    SHIRT_SIZES = (
        ('S', 'Small'),
        ('M', 'Medium'),
        ('L', 'Large'),
    )
    name = models.CharField(max_length=60)
    shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)


class Grade(models.Model):
    score=models.CharField(max_length=60)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)

接口返回下拉选项对应的值

在Person这个model中的shirt_size字段 存储到数据库中的值未S/M/L,但是在前端用户需要看到他们对应value,那么我们接口如何返回呢

需要在模块对应的serializer.py文件中小小的修改一下


class PersonSerializer(serializers.ModelSerializer):
    shirt_size_name = serializers.CharField(source='get_shirt_size_display', required=False)
    class Meta:
        model = Person
        fields = ('id','shirt_size', 'shirt_size_name')

接口返回外键对应的值

在Grade查询接口中返回对应外键人员的姓名,这有两种方法

  1. Grade在序列化的时候,就创建一个新的字段叫 person_name,指定为 serializers.CharField,而且字段使用 source 这个属性,具体而言格式为 CharField(source='<本model中的外键>.<外键指向的model的相应属性>')
```
class GradeSerializer(serializers.ModelSerializer):
    person_name = serializers.CharField(source='person.name'')
    class Meta:
        model = Grade
        fields = ('id','person_name')
```
  1. 在 models 里面 @property 装饰符先创建一个 person_name 函数,这个函数返回的是外键对应 model 的相应字段,比如 person.name。 然后,序列化的时候,指定为 serializers.ReadOnlyField() 类型

这种方法也可以增加给接口增加额外的字段

```
class Grade(models.Model):
    score=models.CharField(max_length=60)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    ...
    ...
    
    @property
    def person_name(self):
        return self.person.name
    
```

```
class GradeSerializer(serializers.ModelSerializer):
    person_name = serializers.ReadOnlyField()
    class Meta:
        model = Grade
        fields = ('id','person_name')
```

模糊查询

首先增加一个过滤器filters.py

		class   PersonFilter(django_filters.rest_framework.FilterSet):
			"""
			人员的过滤类
			"""
			name = django_filters.CharFilter(name='name', lookup_expr='icontains')

			class Meta:
				model = Person
				fields = ('id', 'name')

有时自带的过滤方法无法满足,就需要我们自定义过滤方法,例:

class   PersonFilter(django_filters.rest_framework.FilterSet):
    # 自定义了过滤方法person_filter
    person_name = django_filters.CharFilter(method='person_filter')
    # 通过传入的中文名模糊查询到对应90分数人的ID
    def person_filter(self, queryset, name, value):
        personList = []
        qs = Grade.objects.filter(name__contains=value).filter(score='90')
        if qs.exists():
            for q in qs:
                personList.append(q.id)
        # 返回对应人员的查询集合
        return queryset.filter(id__in=userList)

然后在对应的view中配置一下ViewSet

class PersonViewSet(viewsets.ModelViewSet):
    """
      LIST
        用户列表页, 分页, 搜索, 过滤, 排序

    """
    .......
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
    filter_class = PersonFilter
    search_fields = ('id', 'name')
    ......

转载于:https://my.oschina.net/hellotest/blog/1942564

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值