【问题标题】:Filtering in DRFDRF 中的过滤
【发布时间】:2021-07-29 21:33:39
【问题描述】:

应用程序具有票证模型:

class Ticket(models.Model):
    theme = models.ForeignKey(TicketTheme, on_delete=models.PROTECT)
    user = models.ForeignKey(User, related_name='user', on_delete=models.PROTECT)
    support = models.ForeignKey(User, on_delete=models.PROTECT)
    status = models.ForeignKey(Status, on_delete=models.PROTECT)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

以及票证中的消息模型:

class TicketMessage(models.Model):
    types = [
        ('user_msg', 'user_msg'),
        ('sys_msg', 'sys_msg')
    ]
    ticket = models.ForeignKey(Ticket, on_delete=models.PROTECT)
    text = models.CharField(max_length=250, default='')
    image = models.ImageField(upload_to='ticket_message_img/', default='')
    user = models.ForeignKey(User, on_delete=models.PROTECT)
    type = models.CharField(max_length=50, default='user_msg', choices=types)
    read = models.IntegerField(max_length=1, default=0)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

序列化器:

class TicketSerializer(serializers.ModelSerializer):
    user = serializers.SlugRelatedField(
        slug_field='username',
        read_only=True
    )
    support = serializers.SlugRelatedField(
        slug_field='username', 
        read_only=True
        )
    theme = serializers.SlugRelatedField(
        slug_field='name',
        read_only = True
    )
    status = serializers.SlugRelatedField(
        slug_field='name',
        read_only=True
    )

    class Meta:
        model = Ticket
        fields = '__all__'

class TicketMessageSerializer(serializers.ModelSerializer):
    class Meta:
        model = TicketMessage
        fields = '__all__'

网址:

urlpatterns = [
    path('api/tickets/', views.TicketSerializerView.as_view()),
    path('api/tickets/<int:pk>/all_messages/', views.TicketAllMessagesSerializerView.as_view()),
    path('api/tickets/<int:pk>/messages/', views.TicketMessagesSerializerView.as_view()),
]

控制器:

class TicketSerializerView(generics.ListAPIView):
    queryset = Ticket.objects.all()
    serializer_class = TicketSerializer
    permission_classes = [permissions.IsAuthenticated]

    def create(self, validated_data):
        return Ticket.objects.create(**validated_data)
    
class TicketAllMessagesSerializerView(generics.ListAPIView):
    queryset = TicketMessage.objects.all()
    serializer_class = TicketMessageSerializer
    permission_classes = [permissions.IsAuthenticated]

class TicketMessagesPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 1000

class TicketMessagesSerializerView(generics.ListAPIView):
    queryset = TicketMessage.objects.all()
    serializer_class = TicketMessageSerializer
    pagination_class = TicketMessagesPagination
    permission_classes = [permissions.IsAuthenticated]

问题:

  1. 如何过滤控制器中特定工单的消息(通过工单pk)。现在它显示来自所有工单的所有消息。
  2. 如何仅向创建工单的用户(用户字段)、管理员(超级用户)和处理此工单的经理(支持字段)提供对消息的访问权限

*如果有关于代码的cmets,知道也会很有趣

【问题讨论】:

  • stackoverflow.com/questions/68113403/…第一个问题在这里有答案,但你必须使用create而不是to_represent函数
  • 请记住,像您编写的那样简单的序列化程序功能非常有限。您将不得不使用serializers.Serilaizer 继承并覆盖其功能

标签: django-rest-framework


【解决方案1】:

我重写了控制器、url 和序列化程序:

urlpatterns = [
    path('api/tickets/<int:ticket_id>/messages/',
          views.TicketMessageSerializerView.as_view()),
]


class TicketMessageSerializer(serializers.ModelSerializer):
    class Meta:
        model = TicketMessage
        fields = '__all__'


class TicketMessageSerializerView(generics.ListAPIView):
    queryset = TicketMessage.objects.all()
    serializer_class = TicketMessageSerializer

    def get_queryset(self, *args, **kwargs):
            return super().get_queryset(*args, **kwargs).filter(
                ticket__id=self.kwargs['ticket_id']
            )

【讨论】:

    猜你喜欢
    • 2020-01-14
    • 2020-12-10
    • 2020-11-03
    • 2016-02-23
    • 2018-08-02
    • 2019-05-31
    • 1970-01-01
    • 2020-04-06
    • 2021-10-20
    相关资源
    最近更新 更多