7

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

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

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

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

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

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

我知道如何使它成为一个上下文并将其返回到一个模板,此时我可以用它做任何事情,但我对如何在幕后做这件事感到困惑,所以我可以在返回它之前做剩下的事情给用户。最终字符串应如下所示:

these-are-my-words

此外,我在我的应用程序的哪个位置执行此操作我来自 PHP,在那里,我将有一个functions.php文件或其他东西来执行后端工作并将其排除在演示文稿之外。我发现一些其他人的帖子说他们使用 a functions.py,但我不确定如何包含与现有views.py. 如果我做:

from functions import myfunc

它仅functions.py在文件夹中以及我从中导入它的位置时才有效。

4

4 回答 4

18

要将您的查询集转换为字符串,请使用python 的 join 函数

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

我怀疑这段代码实际上应该存在于您的一个视图中,并且永远不会触及您的数据库,但如果不知道您的应用程序在做什么,这很难说。(您肯定将此字符串传递给模板并将其呈现到 html 页面上吗?)

于 2013-02-24T18:30:25.640 回答
0

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

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

我觉得必须有更好的方法来做到这一点。加入,如建议的那样,没有用,我一直收到一个错误,它需要一个字符串,即使所有文档都说它用于加入列表,而不是字符串,所以我不确定故障在哪里。

于 2013-02-25T04:43:36.543 回答
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 添加一些逻辑,以确保您不会无限循环。

于 2013-02-25T06:31:42.317 回答
0

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

youroutputishere  = '-'.join([str(counterofobjects) for counterofobjects in yourobjects])
于 2020-04-09T10:30:07.850 回答