django从查询集中访问m2m字段属性

时间:2017-07-12 05:32:02

标签: python django

我试图从查询集中显示django模板中M2M字段的属性之一。

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)

现在来自Reservation queryset,我正在尝试访问django模板中的rooms fiels属性,即number(使用jinja模板),

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

views

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

但是抛出以下错误,

'django.db.models.query.QuerySet object' has no attribute 'rooms_set'
我做错了什么?

在尝试回答neverwalkaloner

后,

TraceBack

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

1 个答案:

答案 0 :(得分:2)

找到解决方案,在rooms

中添加了prefetch_related
res = Reservation.objects.filter(hotel=hotel).prefetch_related('rooms')

然后在模板中

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

它现在显示了期望的结果,即房间号码!