I have a ticket model, and its ticket serialiazer. The ticket model has a
*bought* and a *booked_at* field. And also a *unique_together* attribute
for *show* and *seat*.

class Ticket(models.Model):
    show = models.ForeignKey(Show, on_delete=models.CASCADE)
    seat = models.ForeignKey(Seat, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    booked_at = models.DateTimeField(default=timezone.now)
    bought = models.BooleanField(default=False)

    class Meta:
        unique_together = ('show', 'seat')


   - On the ticket serializer, the serializer on validation checks whether
   the ticket was bought or not.
   - If it is bought, then it will raise an error.
      - If its not bought then Check if the ticket was booked within 5
      minutes.
         - If its booked within 5 minutes, then raise an error.
         - Else if the booked time is more than 5 minutes, than delete the
         old ticket and return valid.

TicketSerializer:

class TicketSerializer(serializers.Serializer):
    seat = serializers.PrimaryKeyRelatedField(queryset=Seat.objects.all())
    show = serializers.PrimaryKeyRelatedField(queryset=Show.objects.all())
    user = serializers.PrimaryKeyRelatedField(queryset=User.objects.all())
    bought = serializers.BooleanField(default=False)

    def validate(self, attrs):
        if attrs['seat']:
            try:
                ticket = Ticket.objects.get(show=attrs['show'], seat=seat)
                if not ticket.bought:
                    if ticket.booked_at < timezone.now() -
datetime.timedelta(minutes=5):
                        # ticket booked crossed the deadline
                        ticket.delete()
                        return attrs
                    else:
                        # ticket in 5 mins range
                        raise serializers.ValidationError("Ticket with same
show and seat exists.")
                else:
                    raise serializers.ValidationError("Ticket with same
show and seat exists.")
            except Ticket.DoesNotExist:
                return attrs
        else:
            raise serializers.ValidationError("No seat value provided.")


On the view, I am using *@transaction.atomic()* to make sure the ticket/s
are created only if all of them are valid, or don't create ANY ticket if
not valid.

@transaction.atomic()
@list_route(
    methods=['POST'],
)
def book_tickets_by_show(self, request, show_id=None):
    try:
        show = Show.objects.get(id=show_id)
        user = request.user
        ...
        ...
        data_list = [...]
        with transaction.atomic():
            try:
                serializer = TicketSerializer(data=data_list, many=True)
                if serializer.is_valid():
                    serializer.save()
                    ....
                return Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
            except (Seat.DoesNotExist, ValueError, ConnectionError) as e:
                return Response({'detail': str(e)},
status=status.HTTP_400_BAD_REQUEST)
    except (Show.DoesNotExist, IntegrityError) as e:
        return Response({'detail': str(e)},
status=status.HTTP_400_BAD_REQUEST)

What I would like to know is will it help in preventing when more than one
requests are called for creating the ticket/s for same seat/s?

Suppose, User A wants to book ticket with seat 5,6 and User B wants to book
ticket with seat 3,6, and another User C wants to book the ticket with
seats 2,3,4,5,6. Will the above method prevent booking tickets for their
respective seats for all the users, and only create tickets for one user
(maybe whose transaction was first)? Or if there is a better way then could
you please advice me how to. I hope I was clear. If not please ask.

Thank you

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CAHSNPWsHM%3Dk1ezHr3Vp_k9_4fviz%2B7ZmzZ7iuieZgifLg09k2w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to