1

The application has a ticket model:

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)

And the message model in the ticket:

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)

Serializers:

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__'

Urls:

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()),
]

Controllers:

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]

Questions:

  1. How to filter messages of a specific ticket in the controller (by ticket pk). Now it displays all messages from all tickets.
  2. How to provide access to messages only to the user who created the ticket (the user field), the administrator (superuser) and the manager who took this ticket for processing (the support field)

*if there are comments about the code, it will also be interesting to know

  • https://stackoverflow.com/questions/68113403/assign-pk-form-url-to-models-related-field/68115506#68115506 the first question has answer here but instead of `create` you have to use `to_represent` function – Charalamm Jul 27 '21 at 16:32
  • Keep in mind that the simple serilizers like the one you have written have very limited functionalities. you will have to use the `serializers.Serilaizer` inheritance and override its functions – Charalamm Jul 27 '21 at 16:36

1 Answers1

0

I rewrote controllers, urls and serializers:

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']
            )