Ross Symonds
Ross Symonds

Reputation: 710

Django filter field with foreign key

Update

Thank you Root for your below answer (which I upvoted). Based on your suggestions, I was able to solve my problem. I am now using this -

 try:
    queryset2 = RoomBookings.objects.filter(HotelName__HotelName__icontains=hotel.HotelName)
 except:
     pass

This was working -

    RoomBookings.objects.filter(HotelName__icontains=hotel.HotelName, RoomType__icontains= hotel.RoomType, 
        ArrivalDate__lt=RoomBookingsForm['DepartureDate'], DepartureDate__gt=RoomBookingsForm['ArrivalDate'])

But then I changed the HotelName field in the RoomBookings model from CharField to ForiegnKey. And now I cannot figure out how to do a reverse lookup. These are my failed attempts -

        # queryset2 = RoomBookings.objects.filter(HotelName__HotelName__icontains=hotel.HotelName)
        # queryset2 = RoomBookings.objects.filter(HotelName__Hotel__HotelName__icontains=hotel.HotelName)
       
        # queryset2 = RoomBookings.objects.filter(HotelName__Hotel__HotelName_exact=hotel.HotelName)
        # queryset2 = RoomBookings.objects.filter(HotelName__HotelName_exact=hotel.HotelName)
        



class Hotel(models.Model):
    HotelName               = models.CharField(max_length=60, null=False)
          

    def __str__(self):
        return self.HotelName



class RoomType(models.Model):
    HotelName           = models.ForeignKey(Hotel, null=True, blank=True, on_delete=models.CASCADE)
    RoomType            = models.CharField(max_length=60, null=False, choices=Room_Type)
    

    def __str__(self):
return '{0}, {1}'.format(str(self.HotelName), self.RoomType) 





class RoomBookings(models.Model):
    User               = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
  
    HotelName           = models.ForeignKey(Hotel, null=True, blank=True, on_delete=models.CASCADE)
 
    RoomType            = models.CharField(max_length=60, null=False, choices=Room_Type)
     
    def __str__(self):
     
        return '{0}, {1}, {2}'.format(self.HotelName, self.ArrivalDate, self.RoomType)

Upvotes: 0

Views: 314

Answers (1)

root
root

Reputation: 337

I've tested your code. Your first attempt is perfectly fine.

queryset2 = RoomBookings.objects.filter(HotelName__HotelName__icontains=hotel.HotelName)

But I'm not sure what is coming under hotel.HotelName? Have you tried checking it like print(f"hotel.HotelName: {hotel.HotelName}")? May be it's none and you're not able find your results.

However I've few suggestions for you.

  1. Keep your code clean.

  2. Define some reverse relation names eg. HotelName = models.ForeignKey(Hotel, related_name="hotel", null=True, blank=True, on_delete=models.CASCADE). check the keyword related_name.

  3. try to name your model fields as not exactly as your foreign key model field. for example. hotel = models.ForeignKey(Hotel, related_name="hotel", null=True, blank=True, on_delete=models.CASCADE)

  4. Read the Django documentation carefully.

Thanks. Hopefully it's the answer to your question.

Upvotes: 1

Related Questions