将queryset与Django组合成单个字符串

时间:2013-02-24 18:24:09

标签: python django

假设我有一个非常简单的模型,它只是一个单词列表:

class WordList(models.Model):
    word = models.CharField(max_length=60)

用户提交表单后,我想......

  • 检索四个随机单词
  • 将它们合并为一个字符串
  • 确保先前未生成重复的字符串,如果是,请再次运行
  • 好的时候将它保存到数据库
  • 将结果返回给用户。

我知道如何获得四个随机词:

WordList.objects.order_by('?')[:4]

我知道如何将它作为一个上下文并将其返回到一个模板,此时我可以用它做任何事情,但我很难理解我是如何在幕后做的,所以我可以做其余的事情在将其返回给用户之前。最后的字符串应如下所示:

these-are-my-words

此外,在我的应用中我这样做了吗?我来自PHP,在那里,我会有一个functions.php文件或其他东西来执行后端内容并将其保留在演示文稿之外。我发现其他一些人说他们使用的是functions.py,但我不确定如何包含与现有views.py不在同一文件夹中的外部网页。如果我这样做:

from functions import myfunc

仅当functions.py位于文件夹中时才会起作用,无论我从哪里导入它。

4 个答案:

答案 0 :(得分:12)

要将您的查询集转换为字符串,请使用python's join function

your_string = '-'.join([str(i) for i in WordList.objects.order_by('?')[:4]])

我怀疑这段代码实际上应该存在于您的一个视图中,而且从不触及您的数据库,但是如果不知道您的应用正在做什么,这很难说。 (当然你将这个字符串传递给模板并将其渲染到html页面上?)

答案 1 :(得分:0)

这是最终起作用的。诀窍是我没有意识到可以像Python列表一样访问QuerySet。

dbQuery = WordList.objects.order_by('?')[:4]
result = dbQuery[0]
for word in dbQuery[1:]:
    result = "%s-%s" % (result, word)

我觉得必须有更好的方法来做到这一点。正如建议的那样加入不起作用,即使所有文档都说它用于连接列表而不是字符串,我仍然会收到一个错误,它预期会出现字符串,所以我不确定故障的位置。

答案 2 :(得分:0)

虽然您发布的解决方案“有效”,但它是一种非常PHP的方式。

更多Django方式:

在应用程序的models.py文件中:

from django.db import models


class Word(models.Model):
    word = models.CharField(max_length=60, blank=False, null=False, unique=True)

    def __unicode__(self):
        return u'%s' % self.word


class RandomWordString(models.Model):
    string = models.CharField(max_length=255, blank=False, null=False, unique=True)

    def __unicode__(self):
        return u'%s' % self.string

    @staticmethod
    def generate(length):
        words = Word.objects.order_by('?')[:(length + 1)]
        possible_word_string = '-'.join(words.values_list('word', flat=True))
        try:
            RandomWordString.objects.get(string=possible_word_string)  # See if we've already generated this sequence
            return RandomWordString.generate(length)  # Call ourselves again if we have
        except RandomWordString.DoesNotExist:
            return possible_word_string  # If we haven't, return the value

    def save(self, *args, **kwargs):
        if not self.string or len(self.string) < 1:
            self.string = RandomWordString.generate(3)
        super(RandomWordString, self).save(*args, **kwargs)

然后,从任何视图或其他任何地方:

from words.models import RandomWordString
seq = RandomWordString.generate(3)

因为我们覆盖了保存,我们也可以这样做:

from words.models import RandomWordString
string = RandomWordString.objects.create()
string.save()

这将所有逻辑放在模型本身中,这比在视图中更好地 更好(尽管这完全是品味的问题)。

除了我发布的内容之外,您还需要为RandomWordString.generate添加一些逻辑,以确保不会无限循环。

答案 3 :(得分:0)

您必须表示字符串,以便通过 join函数将查询集与Django组合为单个字符串。 因此,您可以使用 for循环从类的对象中提取字符串:

youroutputishere  = '-'.join([str(counterofobjects) for counterofobjects in yourobjects])