【问题标题】:django queryset returns "classname object" instead of DB valuesdjango queryset 返回“类名对象”而不是 DB 值
【发布时间】:2014-01-27 01:58:24
【问题描述】:

我对 django 查询集有疑问。

型号:

class Rooms(models.Model,):
room_state = models.CharField(max_length=255, choices=[('emptyReady', 'empty'), ('emptyWaiting4Clean', 'clean ready'), ('busy', 'busy')])
room_type = models.IntegerField()
room_number = models.IntegerField()

我可以通过输入 python shell 来检查查询集的工作情况:

for d in Rooms.objects.filter(room_state="emptyReady", id='1'):    print(d)

在我的数据库中有表Rooms_rooms,里面有列room_state,如果我们对数据库进行查询:

SELECT room_state FROM Rooms_rooms where id = 1

返回值为emptyReady

但是当我使用查询集(如上面的示例)时,我总是得到:Rooms object

我做错了什么?我尝试在所有 WEB 中搜索答案 3 小时,现在我的耐心已经结束,所以我指望你们 ;)

【问题讨论】:

    标签: python database django django-queryset


    【解决方案1】:

    这里:

    Rooms.objects.filter(room_state="emptyReady", id='1')
    

    返回Room 对象的查询集。

    现在,如果你想要一个特定的值:

    Rooms.objects.filter(room_state="emptyReady", id='1').values_list('room_state', flat=True)
    

    阅读更多values_list here

    或者:

    for d in Rooms.objects.filter(room_state="emptyReady", id='1'):    print(d.room_state)
    

    另一种方法是在class Room 上指定__unicode__ attribute

    class Rooms(models.Model,):
        room_state = models.CharField(max_length=255, choices=[('emptyReady', 'empty'), ('emptyWaiting4Clean', 'clean ready'), ('busy', 'busy')])
        room_type = models.IntegerField()
        room_number = models.IntegerField()
    
        def __unicode__(self):
            return u'%s' % self.room_state
    

    如果print d 被调用,这应该打印room_state

    【讨论】:

      【解决方案2】:

      如果我理解,您正在尝试使用 Django 模拟以下查询:

      SELECT room_state FROM Rooms_rooms where id = 1
      

      鉴于您的模型,使用 Django,这可以通过发出:

      Rooms.object.filter(room_state='emptyReady', id=1).values('room_state')
      

      values() function 在 Django 1.2 版本(如果不是更早版本)中可用,它允许您仅选择那些您需要查询的字段。这比获取完整模型要快得多,因为它只为您提供包含选定字段的字典。

      请注意,在您的代码中,您将 id 作为字符串而不是数字发送。此外,像 filter()values() 这样的函数永远不会返回集合,而是一个 Django 对象,您需要对其进行迭代以获取值。因此,最后您需要执行以下操作:

      Rooms.object.filter(room_state='emptyReady', id=1).values('room_state')[0]['room_state']
      

      这是故意对delay the effective work until it is truly needed进行的。

      【讨论】:

        【解决方案3】:

        更新和完善@karthikr 的答案...

        如果您尝试获取查询集并将其作为上下文传递给模板,然后在循环中迭代,例如:

        (在views.py中)

        # The manytomanyfield named subscribers in the Feed object points to the userprofile object which has a onetoonefield relationship with the user object
        # [...]
        queryset = Feed.objects.filter(subscribers=request.user.userprofile)
                context = {
                            "result_list"    : queryset,
                }
                return render(request, "subscriptions/subscriptions.html", context)
        

        (在 subscriptions.html 中)

        # [...]
            {% for instance in result_list %}
                <p> {{ instance.pk }} |---> <a href=''>{{ instance.url }}</a> </p>
            {% endfor %}
        # [...]
        

        你会得到错误:

        'Feed' object has no attribute '__name__'
        

        当更改模板以显示 result_list 而不使用 for 循环时,例如:

        # [...]
        {{ result_list }}
        # [...]
        

        我看到了与 OP 相同的输出(这是渲染器输出的):

        <QuerySet [<Feed 'https://news.ycombinator.com/rss'>
        

        在我的例子中是Feed object 而不是Rooms object

        最初尝试循环遍历result_list 时,当模板渲染器认为字符串 Feed 是查询集的列或对象本身的实例时,就会出现错误,然后尝试确定调用它的内容在类似字典的数据结构中。

        我不知道为什么在我的情况下 Feed.objects.filter() 或在 OP 的情况下 Rooms.objects.filter() 决定包含不带引号的类名,从而混淆模板渲染器。

        我的解决方案是将我的查询更改为:

        queryset = Feed.objects.filter(subscribers=request.user.userprofile).values_list('pk','url', named=True)
        

        使用named=True 对能够在模板中单独处理列值很重要(例如{{ instance.pk }})。使用上面的查询和如上所示的subscriptions.html 模板中的for-loop,渲染顺利进行:

        1 |---> https://news.ycombinator.com/rss
        

        【讨论】:

          猜你喜欢
          • 2017-10-06
          • 2016-09-05
          • 2021-07-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-26
          • 2018-07-21
          • 1970-01-01
          相关资源
          最近更新 更多