简体   繁体   中英

Blank Result When Filtering ForeignKey values in Django ModelchoiceField

I have three models and they serve as 'Foreignkey' to each other.

Hotel models

class Hotel(model.Models):
  user= models.ForeignKey(User)
  name= models.CharField(max_length=100, verbose_name='hotel_name')
  address= models.CharField(max_length=100, verbose_name='hotel_address') 
  #more fields

Rooms models

class HotelRooms(models.Model):
    hotel= models.ForeignKey(Hotel, related_name='myhotels')
    slug=models.SlugField(max_length=100, unique=True)
    room_name=models.CharField(max_length=100, verbose_name='Room Name')
    #other fields

HotelCalendar models

class HotelCalendar(models.Model):
    user=models.ForeignKey(User)
    hotel=models.ForeignKey(Hotel)
    hotelrooms=models.ForeignKey(HotelRooms)
     #other fields

Now, I want to display all rooms that belongs to a hotel in HotelCalender form in order for the owner to select the room he/she wants to update and save.

HotelCalendar form

class HotelCalendarForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(HotelCalendarForm, self).__init__(*args, **kwargs)
        self.fields['hotelrooms'].queryset=  HotelRooms.objects.filter(hotel=self.instance.hotel_id)

Template

<form id="post_form" method="post" action=""
      enctype="multipart/form-data">

     {% csrf_token %}

     {{  HotelCalendarForm.as_p }}


    <input type="submit" name="submit" value="Submit" />
</form>

Views

def hotel_calendar_view(request, hotel_id):
    if request.method=="POST":
        form=HotelCalendarForm(request.POST)
        if form.is_valid():
            data=form.cleaned_data
            newbookdate=HotelCalendar(
                user=request.user,
                hotel=Hotel.objects.get(id=hotel_id),
                hotelrooms=data['hotelrooms'],)
            newbookdate.save()
            return render(request, 'notice.html')
            #other code here

When I load the form, it won't return any value, The modelchoicefield is just blank.

What am I missing?

You should modify the line

self.fields['hotelrooms'].queryset = HotelRooms.objects.filter(hotel=self.instance.hotel_id)

to

self.fields['hotelrooms'].queryset = HotelRooms.objects.filter(hotel=self.instance.hotel)

When you are filtering on foreign key it expects a model instance. If you would want to filter on foreign key you would have to do it like this:

HotelRooms.objects.filter(hotel_id=self.instance.hotel_id)

If you want to know more read https://docs.djangoproject.com/ja/1.9/topics/db/queries/#field-lookups

It seems you are trying to populate the hotelrooms field with the filtered results by the hotel when the form is loaded on a GET request. If that's the case the field wont load any data as the instance variable will be None .

For the initial data you need to pass the hotel id to the form when it is being initialized on the GET request and in the form, load the data using the hotel id and not instance.hotel_id . For example:

views.py

@login_required
def hotel_calendar_view(request, hotel_id):
    if request.method=="POST":
        ## code to post the form data
    else:
        context = {
            'HotelCalendarForm’: HotelCalendarForm(hotel_id=hotel_id),
            'hotel': Hotel.objects.get(id=hotel_id)
        }
        return render(request, 'hotels/hotel_calendar.html', context)
    # return default response

and then in your forms:

forms.py

class HotelCalendarForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        hotel_id = kwargs.pop(“hotel_id”, None)
        super(HotelCalendarForm, self).__init__(*args, **kwargs)
        if hotel_id:
            self.fields['hotelrooms'].queryset=HotelRooms.objects.filter(hotel=hotel_id)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM