2013-02-24 40 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