2016-05-26 68 views
0

這是我試圖實現的一個過於簡單的示例。比方說,我有這兩種模式:Django - 從隨機數據庫條目創建動態表單

class Question(models.Model): 
    text = models.CharField(max_length=255) 

class Answer(models.Model): 
    text = models.CharField(max_length=255) 
    question = models.ForeignKey(Question) 

而且讓我們說我有成千上萬的數據庫中的問題,但我希望每個用戶只回答一些隨機的。所以,我的想法是創建一個動態表單。這樣的事情:

class QuestionnaireForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     super(QuestionnaireForm, self).__init__(*args, **kwargs) 

     questions = list(Question.objects.all()) 
     random.shuffle(questions) # it successfully validates without this line 
     questions = questions[:3] 

     for q in questions: 
      self.fields[q.text] = forms.CharField() 

當我這樣做,我得到我的三個隨機問題,但表單不會驗證。如果我評論洗牌,一切正常,但我明顯每次都會得到同樣的問題。

從我可以看到,它似乎像Django再次在表單提交中調用__init__方法,從而重複洗牌和獲取不同的問題。我嘗試閱讀文檔,但我並沒有設法繞過我的頭,爲什麼它是這樣。

+0

當然,它會在提交時調用init;這就是你的觀點。 –

回答

1

Random ordering

questions = Question.objects.all().order_by('?')[:3] 

爲了驗證形式,它hink,你需要恢復相同的查詢集的東西,如:

questions = Question.objects.filter(pk__in=request.POST.getlist('ids')) 

,並把它形成。想想你也需要保存相同的順序 - 那麼你可以在窗體中整理這個列表。

更新:

您應該保存請求之間的狀態的一些方式。您可以添加隱藏字段,添加URL參數,設置Cookie,將信息保存在用戶個人資料中 - 完全取決於您的選擇。最典型的方法是設置隱藏的輸入(一般是默認的django ModelForm行爲)。

因此,在第一次請求時,當您顯示錶單時 - 您將得到queryset,按pk對其進行排序,例如將其放入表單並添加帶有ID的隱藏字段。當用戶使用回答發出POST請求時 - 您將使用此ID恢復您的查詢集,以同樣的方式對其進行重新排序並將其置於窗體進行驗證。

+0

這不僅是隨機排序,而且當表單發佈時再次得到相同的問題。這種方法也會在GET和POST請求中產生不同的問題。 – AKS

+0

沒有。問題依然存在。爲了提高效率,我使用了_random.shuffle_,但它的功能基本相同。 –

+0

我已經更新了答案。 – qnub