I'm developing a Tutor management system. 

The user posts which lesson he would like a tutor for and a time range that 
suits him. The web app finds at most 5 suitable tutor Profiles and creates 
an Appointment for each of them(This is sort of like a Reservation). These 
profiles are sent back to the user and he picks his preferred one. 

class AppointmentView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request, format='json'):
        profile             = Profile.objects.get(user__id=request.user.id)
        lesson              = None
        address             = None
        timezone_name       = None
        date                = None
        appointment_time    = None

        try:
            lesson = Lesson.objects.get(id=int(request.data['lesson']))
        except KeyError:
            return bad_request({'lesson': 'lesson missing from request body'})
        except Lesson.DoesNotExist:
            raise Http404('A lesson with the given id does not exist')

        try:
            address = Address.objects.get(id=int(request.data['address']))
            if address.profile.id is not profile.id:
                return bad_request({'address':'This address does not belong to 
the user'})
        except KeyError:
            return bad_request({'address':'address missing from request body'})
        except Address.DoesNotExist:
            raise Http404('An address with given id does not exist')

        try:
            sdate = request.data['date']
            date = parser.parse(sdate)
        except KeyError:
            return bad_request({'date':'date missing from request body'})

        try:
            _timezone_name = request.data['timezone']
            if _timezone_name not in all_timezones:
                return bad_request({'timezone':'%s is not a recognized 
timezone'%_timezone_name})
            timezone_name = _timezone_name
        except KeyError:
            return bad_request({'timezone':'timezone missing from request 
body'})

        tz = timezone(timezone_name)
        appointment_time = tz.localize(date)

        starting_time       = appointment_time.strftime('%H:%M:%S')
        ending_time         = (appointment_time + 
lesson.duration).strftime('%H:%M:%S')
        day_of_week         = appointment_time.strftime('%a')


        availabilities = Availability.objects.filter(
            Q(starting_time__lte=starting_time) &
            Q(ending_time__gte=ending_time) &
            Q(timezone=timezone_name) &
            Q(day_of_week=day_of_week) &
            Q(profile__teaches__lesson=lesson) & 
            
~Q(appointments__date__range=(appointment_time,appointment_time+lesson.duration))
        ).exclude(
            profile=profile
        )

        if availabilities:
            profiles = []
            random_48_bits = random.randint(0,2 ** 48 - 1)
            request_id = uuid.uuid1(random.randint(0,random_48_bits))

            for availability in availabilities:
                Appointment.objects.create(
                    availability    = availability,
                    student         = profile,
                    lesson          = lesson,
                    date            = appointment_time,
                    status          = STATUS_AWAITING_TUTOR_SELECTION,
                    request_id      = request_id
                )

                profiles.append(availability.profile)

            a = ProfileAvailabilitySerializer(
                    instance=profiles,
                    many=True,
                    context={'availabilities':availabilities}
                )

            return Response(a.data)

        return not_found({'error':'No tutors available for this period'})

In the above code, it can be seen that I send the availabilities and the 
profiles to the ProfileAvailabilitySerializer. In the serializer, I try to 
show the availability corresponding to each profile.

The problem I'm having is that when I try to filter the availabilities by 
profile, it always returns an empty set.

class ProfileAvailabilitySerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    availability = serializers.SerializerMethodField()
    addresses = AddressSerializer(many=True)
    class Meta:
        model = Profile

    def get_availability(self, profile):
        availabilities = self.context['availabilities']
        print >> sys.stderr, availabilities # Output: [<Availability: 
Profile.id 1 - Sat 18:00:00 - 19:30:00 Asia/Dubai>]
        print >> sys.stderr, profile.id # Output: 1
        data = availabilities.filter(
            profile=profile
        )
        print >> sys.stderr, data # Output: []
        return AvailabilitySerializer(instance=data, many=True).data

Result:

[
  {
    "id": 1,
    "user": {
      "username": "jack_torrence",
      "first_name": "Jack",
      "last_name": "Torrence",
      "email": "[email protected]"
    },
    "availability": []}]

If I do not create the Appointment in AppointmentView, then the code works 
fine and the availabilities corresponding to the profile are shown.

[
  {
    "id": 1,
    "user": {
      "username": "jack_torrence",
      "first_name": "Jack",
      "last_name": "Torrence",
      "email": "[email protected]"
    },
    "availability": [
      {
        "id": 5,
        "timezone": "Asia/Dubai",
        "day_of_week": "Sat",
        "starting_time": "18:00:00",
        "ending_time": "19:30:00",
        "profile": 1
      }
    ]}

Where could I be going wrong? I'm not sure if it's a logical error or 
something related to Django.

*Models*

class Availability(models.Model):
    profile         = 
models.ForeignKey(Profile,on_delete=models.CASCADE,related_name='availability')
    day_of_week     = models.CharField(max_length=3,choices=DAY_OF_WEEK_CHOICES)
    starting_time   = models.TimeField()
    ending_time     = models.TimeField()
    timezone        = TimeZoneField()

    class Meta:
        unique_together = (
            ('profile','day_of_week','timezone','starting_time'),
            ('profile','day_of_week','timezone','ending_time')
        )

    def owner(self):
        return self.profile.user

    def __str__(self):
        return "%s - %s %s - %s %s" % (
            self.profile.id,
            self.day_of_week, 
            self.starting_time, 
            self.ending_time, 
            self.timezone
        )

class Appointment(models.Model):
    availability    = 
models.ForeignKey(Availability,on_delete=models.PROTECT,related_name='appointments')
 
    student         = 
models.ForeignKey(Profile,on_delete=models.CASCADE,related_name='appointments')
    lesson          = 
models.ForeignKey(Lesson,on_delete=models.PROTECT,related_name='appointments')
    date            = models.DateTimeField()
    status          = models.PositiveSmallIntegerField(choices=STATUS_CHOICES)
    request_id      = models.UUIDField(unique=False, blank=True, null=True)

    def owner(self):
        return self.availability.profile.user

    def __str__(self):
        return "Lesson:%s, Student: %s, Teacher: %s, Date: %s [Status: %s]" % (
            self.lesson,
            self.student,
            self.owner(),
            self.date,
            STATUS_DICT[self.status]
        )

    class Meta:
        unique_together = (
            ('availability','date'),
        )

-- 
You received this message because you are subscribed to the Google Groups 
"Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to