如何在Django中编写多个过滤器

时间:2017-09-08 10:46:35

标签: python django python-3.x django-rest-framework django-views

我很困惑如何在serializers.py中编写过滤器代码。 我有以下型号。

User (AbstractBaseUser)
    userid = models.CharField(max_length=64, primary_key=True)
    username = models.CharField(max_length=128)


Clinic (models.Model)
    clinic_id = models.CharField(max_length=8, primary_key=True)
    clinic_name = models.CharField(max_length=64)


Consultation (models.Model)
    consultation_id = models.AutoField(primary_key=True)
    clinic_id = models.ForeignKey(Clinic)
    user = models.ForeignKey(User)


Chat (models.Model)
    chat_id = models.AutoField(primary_key=True)
    consultation_id = models.ForeignKey(Consultation)
    DIDRESPONSE_CHOICE = {
        ('R', 'No'),
        ('C', 'Doing'),
        ('F', 'Done'),
    }
    did_response = models.CharField(max_length=1, choices=DIDRESPONSE_CHOICE, default='N')


ChatDetail (models.Model)
    chat_no = models.AutoField(primary_key=True)
    chat_id = models.ForeignKey(Chat)
    CHATFROM_CHOICE = {
        ('D', 'Doctor'),
        ('U', 'User'),
    }
    chat_from = models.CharField(max_length=1, blank=True, null=True)
    chat = models.CharField(max_length=512, blank=True)

我想以JSON格式序列化上述数据并响应客户端。

{
    'username': 'Tom Smith',
    'clinic_name': 'Adam's clinic',
    'consultation_id': 12345678, 
    'chat_id': 09876543, 
    'chat_detail' : [ 
        {'chat_no': 11122233, 'chat_from': 'D', 'chat': 'How are you doing today?'}, 
        {'chat_no': 11112234, 'chat_from': 'U', 'chat': 'I have a headache'},
        {'chat_no': 11122235, 'chat_from': 'D', 'chat': 'Oh, I'm sorry'},
        {'chat_no': 11122236, 'chat_from': 'U', 'chat': 'Can you help me?'},
    ] 
} 

我使用override get_queryset方法在views.py中创建了过滤器。但这不是没有用的。所以,我试着在serializers.py中编写过滤器。但它也没有用(我不明白如何在serializers.py中编写上面的需求过滤器。)

我应该怎样做才能达到我的要求?请帮帮我。

views.py

class WebViewChatDataOutputView(APIView):

    def get(self, request, format=None):
        chat_detail = ChatDetail
        serializer = WebViewChatDataOutputSerializer(chat_detail, many=True)
        filter_fields = ('chat_id')
        return Response(serializer.data)

    def get_queryset(self):
        consultation_id = self.request.consultation_id
        chat = Chat.objects.filter(consultation_id=consultation_id)
        return ChatDetail.objects.filter(chat_id=chat.chat_id)

serializers.py

class WebViewChatDataOutputSerializer(serializers.ModelSerializer):

    # class Meta:
    #     model = Consultation
    #     fields = ('consultation_id')
    #
    # class Meta:
    #     model = Chat
    #     fields = ('chat_id')
    #
    class Meta:
        chat = ChatDataForChatDetailSerializer(many=True)
        model = ChatDetail
        fields = ('chat_no', 'chat_from', 'chat')

我正在尝试制作过滤器。但我得到了'Meta.fields';包含未在此FilterSet上定义的字段:ChatDetail,Chat“error。

我的观点如下。

from .filtering import CategoryFilter

class WebViewChatDataOutputView(generics.RetrieveAPIView):
    def get(self, request, format=None):

        filter_backends = (
            rest_framework.filters.OrderingFilter,
            rest_framework.filters.DjangoFilterBackend
        )

        filter_class = CategoryFilter

        serializer = WebViewChatDataInputSerializer(chat_detail, many=True)
        return Response(serializer_class.data)

我的filtering.py如下。

class CategoryFilter(rest_framework.filters.FilterSet):

    name = django_filters.CharFilter(
        name=ChatDetail,
        lookup_expr='chat_id'
    )
    parent_category_name = django_filters.CharFilter(
        name=Chat,
        lookup_expr='chat_id'
    )

    class Meta:
        model = ChatDetail
        fields = ['ChatDetail', 'Chat']

我是否误解了任何一种语法?请提出建议。

我更新了我的代码。

views.py

class WebViewChatDataOutputView(generics.RetrieveAPIView):
    def get(self, request, format=None):

        lookup_field = 'chat_id'
        queryset = Chat.objects.all()
        serializer_class = ChatSerializer

        return Response(serializer_class.data)

serializers.py

class ChatDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = ChatDetail
        fields = '__all__'


class ChatSerializer(serializers.ModelSerializer):

    username = serializers.CharField(source='consultation_id.user.username')  # You should rename the consultation_id foreign key field to consultation, by the way
    clinic_name = serializers.CharField(source='consultation_id.clinic_id.clinic_name')  # Same goes for clinic_id
    chat_detail = ChatDetailSerializer(many=True, source='chatdetail_set')

    class Meta:
        model = Chat
        fields = ('user_name', 'clinic_name', 'consultation_id', 'chat_id', 'chat_detail')

2 个答案:

答案 0 :(得分:2)

我在下面介绍了几种解决方案,以便为您的终端实现过滤器。

您可以使用 filter_class ,但要使用 ListApiView 。创建 filtering.py 并添加一些内容(快速示例):

import django_filters
import rest_framework.filters

from categories import models as categories_models


class CategoryFilter(rest_framework.filters.FilterSet):
    name = django_filters.CharFilter(
        name='name',
        lookup_expr='icontains'
    )
    parent_category_name = django_filters.CharFilter(
        name='parent_category__name',
        lookup_expr='icontains'
    )

    class Meta:
        model = categories_models.Category
fields = ['name', 'parent_category_name']

在您的视图中添加:

import rest_framework.filters

filter_backends = (
        rest_framework.filters.OrderingFilter,
        rest_framework.filters.DjangoFilterBackend
    )

filter_class = categories_filtering.CategoryFilter

More details you find in ListApiView inspector

很明显,因为你有另一个文件只有过滤器逻辑,它与你的序列化器分开。

你也可以使用** get_queryset ,但首先你需要添加statment来检查url,例如:**

  1. url包含带有过滤器字段的q参数
  2. 在方法中你需要获得q值并使用这些
  3. 编写查询来执行此操作
  4. 但更好的想法是使用(你需要更改为Generic): Filter_queryset

答案 1 :(得分:0)

在我看来,您的问题不是过滤,在DRF意义上或QuerySet意义上,您只需要为您的模型提供正确的序列化程序和视图。

您分享的输出是指给定的Chat。对于序列化程序,您需要ChatSerializerChatDetailSerializer(对于ChatDetail的列表)。

您可以使用序列化程序字段中的source参数从相关模型中检索数据,因此ChatSerializer可能如下所示:

class ChatSerializer(serializers.ModelSerializer):

    username = serializers.CharField(source='consultation_id.user.username')  # You should rename the consultation_id foreign key field to consultation, by the way
    clinic_name = serializers.CharField(source='consultation_id.clinic_id.clinic_name')  # Same goes for clinic_id
    chat_detail = ChatDetailSerializer(many=True, source='chatdetail_set')

    class Meta:
        model = Chat
        fields = ('user_name', 'clinic_name', 'consultation_id', 'chat_id', 'chat_detail')

ChatDetailSerializer可以是一个简单的ModelSerializer

class ChatDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = ChatDetail 
        fields = '__all__'

在您的视图中,DRF需要知道如何获取数据。您可以使用get_queryset,但如果您在ApiView上实施,则无效,请使用RetrieveView,因为您要显示一个模型实例({{1} })。或者根据您的需要使用其他一些通用视图(请参阅有关主题的DRF文档,http://www.django-rest-framework.org/api-guide/generic-views/#retrieveapiview)。

ChatDetail

就是这样。我希望你弄清楚。

相关问题