我很困惑如何在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')
答案 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,例如:**
但更好的想法是使用(你需要更改为Generic): Filter_queryset
答案 1 :(得分:0)
在我看来,您的问题不是过滤,在DRF意义上或QuerySet意义上,您只需要为您的模型提供正确的序列化程序和视图。
您分享的输出是指给定的Chat
。对于序列化程序,您需要ChatSerializer
和ChatDetailSerializer
(对于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
就是这样。我希望你弄清楚。