简体   繁体   中英

django access m2m field attribute from a queryset

I am trying to show one of attribute of a M2M field in django template from a queryset.

class Reservation(models.Model):
    hotel = models.ForeignField(Hotel)
    rooms = models.ManyToManyField(Room, through='ReservationRoom')

class Room(models.Model):
    number = models.IntegerField(default=0)

class ReservationRoom(models.Model):
    reservation = models.ForeignKey(Reservation, related_name='reservation_rooms', on_delete=models.PROTECT)
    room = models.ForeignKey(Room, on_delete=models.PROTECT)
    room_type = models.ForeignKey(RoomType, related_name='reservation_rooms', on_delete=models.PROTECT)

Now from Reservation queryset, i am trying to access rooms fiels attribute ie number in django template(using jinja template)like this,

 {% for res in reservations %}
     <tr>
        <td>{{ loop.index }}</td>
        {% for room in reservations.rooms_set.all%}
           <td>{{ room.number }}</td>
        {% endfor %}
     </tr>
 {% endfor %} 

and the views

  def arrivals(request, hotel):
     res = Reservation.objects.filter(hotel=hotel)
     return render(request, "sample.html", {'reservations': res})  

But throwing following error,

'django.db.models.query.QuerySet object' has no attribute 'rooms_set'

what i have done wrong?

TraceBack after tried answer of neverwalkaloner

Traceback Switch to copy-and-paste view

/home/rayhan/work/venv/local/lib/python2.7/site-
packages/django/core/handlers/exception.py in inner
        response = get_response(request) ...
▶ Local vars
/home/rayhan/work/venv/local/lib/python2.7/site-
packages/django/core/handlers/base.py in _legacy_get_response
        response = self._get_response(request) ...
▶ Local vars
/home/rayhan/work/venv/local/lib/python2.7/site-
packages/django/core/handlers/base.py in _get_response
            response = self.process_exception_by_middleware(e, 
request) ...
▶ Local vars
/home/rayhan/work/venv/local/lib/python2.7/site-
packages/django/core/handlers/base.py in _get_response
            response = wrapped_callback(request, *callback_args, 
**callback_kwargs) ...
▶ Local vars
/home/rayhan/work/XercesBlue/core/rbac/decorators.py in _wrapped_view
                    return view_func(request, hotel, *args, **kwargs) 
...
▶ Local vars
/home/rayhan/work/XercesBlue/pms/guest/views.py in arrivals
return render(request, "pms/guest/arrivals.html", {'reservations': 
res, 'arrivals': True}) ...
▶ Local vars
/home/rayhan/work/venv/local/lib/python2.7/site-
packages/django/shortcuts.py in render
content = loader.render_to_string(template_name, context, request, 
using=using) ...
▶ Local vars
/home/rayhan/work/venv/local/lib/python2.7/site-
packages/django/template/loader.py in render_to_string
return template.render(context, request) ...
▶ Local vars
/home/rayhan/work/venv/local/lib/python2.7/site-
packages/django_jinja/backend.py in render
    return mark_safe(self.template.render(context)) ...
▶ Local vars
/home/rayhan/work/venv/local/lib/python2.7/site-
packages/jinja2/environment.py in render
    return self.environment.handle_exception(exc_info, True) ...
▶ Local vars
/home/rayhan/work/venv/local/lib/python2.7/site-
packages/jinja2/environment.py in handle_exception
    reraise(exc_type, exc_value, tb) ...
▶ Local vars
/home/rayhan/work/XercesBlue/templates/pms/guest/arrivals.html in top-
level template code
{% do sidebar_items.user.update({'children': True}) %} ...
▶ Local vars
/home/rayhan/work/XercesBlue/templates/pms/base.html in top-level 
template code
    {% block content %} ...
▶ Local vars
/home/rayhan/work/XercesBlue/templates/pms/guest/arrivals.html in 
block "content"
                                    {% for room in res.rooms.all %} 
...
▶ Local vars


TypeError at /exe/hotel/260/guest/arrivals/
'instancemethod' object is not iterable
Request Method: GET
Request URL:    http://localhost:8000/exe/hotel/260/guest/arrivals/
Django Version: 1.11
Exception Type: TypeError
Exception Value:    
'instancemethod' object is not iterable

Found solution, added rooms in the prefetch_related ,

res = Reservation.objects.filter(hotel=hotel).prefetch_related('rooms')

and then in the template,

{% for room in res.rooms.all() %}
   <td>{{ room.number }}</td>
{% endfor %}

and its now showing the desired result ie the room numbers!

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