django queryset返回“classname object”而不是DB值

时间:2014-01-08 19:18:21

标签: python database django django-queryset

我的django queryset有问题。

模型:

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检查queryset的工作:

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

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

SELECT room_state FROM Rooms_rooms where id = 1

返回值为 emptyReady

但是当我使用queryset时(例如上面的例子)我得到了:房间对象

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

3 个答案:

答案 0 :(得分:4)

下面:

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

如果room_state被调用

,则此值应为print d

答案 1 :(得分:0)

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

SELECT room_state FROM Rooms_rooms where id = 1

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

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

自版本1.2以来,values() function在Django中可用(如果不是更早),并且只允许您选择需要查询的字段。这比获得完整模型要快得多,因为它只给你一个包含所选字段的字典。

请注意,在您的代码中,您将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完成的。

答案 2 :(得分:0)

@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循环,呈现过程顺利进行:

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