【问题标题】:Django - dynamic form creation from random db entriesDjango - 从随机数据库条目创建动态表单
【发布时间】:2016-05-26 05:16:17
【问题描述】:

这是我想要实现的目标的一个过于简单的示例。假设我有这两个模型:

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__ 方法,因此重复了洗牌并得到了不同的问题。我尝试通读文档,但无法理解为什么会这样。

【问题讨论】:

  • 当然它在提交时调用init;这就是您的视图的作用。

标签: python django forms django-forms django-validation


【解决方案1】:

Random ordering

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

它认为,要验证表单,您需要使用以下内容恢复相同的查询集:

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

并将其定型。认为您还需要保存相同的排序 - 然后您可以在表单中整理此列表。

更新:

您应该以某种方式在请求之间保存状态。您可以添加隐藏字段、添加 URL 参数、设置 cookie、在用户个人资料中保存信息 - 由您选择。典型的方式是设置隐藏输入(通常是默认的 django ModelForm 行为)。

所以在第一次请求时,当你显示表单时——你会得到查询集,例如按pk 对其进行排序,放入表单并添加带有 ID 的隐藏字段。当用户发出带有答案的 POST 请求时——您将使用此 ID 恢复您的查询集,以同样的方式再次对其进行排序并放入表单进行验证。

【讨论】:

  • 这不仅仅是随机排序,而是在发布表单时再次得到相同的问题。这种方法还会在 GET 和 POST 请求中生成不同的问题。
  • 不。问题依然存在。我使用 random.shuffle 来提高效率,但它的作用基本相同。
  • 我已经知道我需要恢复相同的 qs 才能使其正常工作,但我不确定如何操作。您是否建议我将 id 列表作为隐藏输入放入表单中?如果您能详细说明一下,我将不胜感激。
  • @ЛудиМачак 我已经更新了详细描述的答案。
猜你喜欢
  • 2023-03-26
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 2017-02-24
  • 2019-05-05
  • 2016-11-11
  • 2012-05-21
  • 1970-01-01
相关资源
最近更新 更多