2013-02-24 44 views
3

说我有一个非常简单的模型,这只是一个单词的列表:组合查询集为一个字符串使用Django

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

当用户提交一个表单,我想......

  • 获取4个随机单词
  • 它们合并成一个字符串
  • 确保重复串先前尚未产生,如果是的话,再次运行
  • 将数据保存到数据库中
  • 将结果返回给用户。

我知道如何获得4次随机的话:

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

我知道如何使这个上下文并返回给模板,在这一点上,我可以做任何它,但我我难以理解我在幕后如何做到这一点,所以我可以在将其返回给用户之前先完成剩余的工作。最终的字符串应该是这样的:

these-are-my-words 

此外,其中在我的应用我做到这一点?我来自PHP,在那里,我会有一个functions.php文件或其他东西来执行后端的东西,并保持它的演示文稿。我发现其他人发表的其他帖子指出他们使用functions.py,但我不确定如何包含与现有views.py不在同一文件夹中的外部页面。如果我做的:

from functions import myfunc 

它只有functions.py是在文件夹中的任何地方我从导入它的工作原理。

+0

那么你的问题是什么?你在问关于查询集或如何在Python中进行导入? – miki725 2013-02-24 18:28:01

+0

@ miki725是的。什么是最好的方式来做到这一点,并在哪里?我找到了第一部分的答案,目前在我的视图中有。有什么地方应该活着吗?我可以弄清楚如何进行导入,但Django最佳实践是什么? – subvertallchris 2013-02-25 04:54:17

回答

8

要将您的查询集变成字符串,请使用python's join function

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

我怀疑这个代码实际上是住在你的意见之一,从来没有接触你的数据库,但很难说没有知道什么您的应用程序在做什么。 (当然,你将这个字符串传递给一个模板,并将其呈现在HTML页面上?)

+0

这是抛出一个错误,它期望一个字符串,但被给予一个列表。加入似乎是正确的做法,但它只是不工作。我发布了我如何最终做出答案,但让我知道是否有更好的方法来做到这一点。 – subvertallchris 2013-02-25 04:41:03

+0

与您的解决方案相比,加入是更好的方法。我做了一个应该解决你的问题的编辑。 – miki725 2013-02-25 05:40:29

+0

谢谢@ miki725。 – 2013-02-25 07:18:41

0

这是什么结束了工作。诀窍是我没有意识到QuerySet可以像Python列表那样被访问。

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

我觉得必须有更好的方法来做到这一点。如所暗示的那样,加入并没有奏效,但我仍然得到一个错误信息,即使所有的文档都说它用来连接列表而不是字符串,所以我不确定崩溃的位置。

+0

对不起,我应该检查我的代码。 miki725已经更正了我的答案,用可迭代的字符串列表替换了查询集。 – 2013-02-25 07:18:19

0

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

更多的Django方式:

在您的应用程序的模型。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以确保您不会无限循环。

+0

在我看来,你是对的,最好是在模型中有逻辑,但是你不应该过度使用它。数据库的原则之一是不要存储重复的数据,除非您有很好的理由,否则您可以轻松生成这些数据。在这种情况下,生成想要的字符串是微不足道的,因此逻辑更好地适合视图而不是模型。另外,将生成的字符串存储起来会带来一大堆问题,例如Word更新时发生的情况。所有使用它的字符串应该更新吗? – miki725 2013-02-25 15:54:38

+0

我不会在WordList和Word之间存储链接,因为那会很疯狂(尽管我猜你可以做到)。 – 2013-02-25 17:16:31

+0

在这种情况下,它将立即进入数据库。有一个单独的表格可以跟踪生成的字符串以及用户提供的其他信息。不用担心它会复制数据或处理不断变化的单词。非常简单的小项目,重建我在PHP中做的一些事情来学习更多Django。因为它主要与数据库交互,所以我觉得这应该在模型中去。 – subvertallchris 2013-02-25 17:23:28