如何用Django表单查询数据库



我有一个模型:

class Registration(models.Model):
student_name = models.CharField(max_length=50)
season = models.ForeignKey(Season, on_delete=models.CASCADE)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
address = models.TextField()
class Meta:
unique_together = (('student_name', 'selected_season', 'selected_subject'),)

我想为这个模型创建一个表单,用户可以根据他们选择的season选择subject。我也有他们的模型:

class Subject(models.Model):
subject_name = models.CharField(max_length=50)
...
class Season(models.Model):
season = models.CharField(max_length=2, primary_key=True)
subject = models.ManyToManyField(Subject)
...

我不知道如何查询表单。它应该是ModelForm还是常规Form?如何查询表单中的数据库?

您只能知道在提交表单时选择了哪个季节,因此没有简单直接的方法来实现这一点(请注意,这是HTTP限制,而不是django限制(。IOW您将需要一个"向导"过程或前端脚本。

"向导"解决方案是:第一个表单,用户选择季节,用户提交表单,您的代码选择相关主题,然后显示第二个表单,其中包含主题选择,用户选择主题并提交以进行最终验证(注:这通常在单个视图中完成,使用表单隐藏字段来跟踪当前步骤以及在第一步中选择了哪个季节(。这是允许工作的(当然如果xD实现正确的话(,但不是真正的用户友好型。

第二种解决方案是使用前端脚本。

在最简单的形式中,当用户选择季节时,您可以使用js隐藏其他季节主题(或者您首先隐藏所有主题,并在选择季节时只显示相关主题(。这可以很简单地通过将给定季节的所有主题分组在同一个字段集中(或任何其他容器标签(,id与该季节的id相匹配,或者每个季节都有一个不同的html"select"(名称相同但id不同(来实现。当然,你也可以在一个html select(或其他(中选择所有主题,保留季节=>主题的前端(js(映射,并从该映射中更新你的select或其他。

这个解决方案可以在没有JS的情况下工作(在"降级"模式下((你只需要确保主题选择器在默认情况下是可见和活动的(。您必须实现自定义验证后端(参见django的表单文档(,以确保主题与季节相匹配(永远不要信任前端验证,这只是用户友好的糖(,因此在最坏的情况下,表单将无法验证。

现在,如果你有很多季节和主题,你可能更喜欢在用户选择季节并从查询结果中填充主题选择器时进行ajax查询(以避免最初呈现大量选项(,但如果没有JS,你就无法再让它工作了(这是否是一个问题取决于你的需求(。

编辑

如果我遵循表单向导选项,我需要创建两个表单,第一个表单只包含季节。

好吧,你可以用一个表单来完成(传递一个参数来指定应该做什么(,但使用两个表单确实要简单得多。

第二个表格将由其他选项组成(季节除外(,对吗?那么第二个形式应该是一个模型形式吗?

好吧,这就是模型形式的意义所在,不是吗?

如何将查询集以模型形式放入ModelChoiceField?我在谷歌上搜索了一下,但什么也找不到——

在表单的__init__中,使用筛选的查询集更新self.fields["subject"].queryset

重要:不要尝试触摸self.fieldname-这是类级别的字段定义,因此更改它将在生产中产生完全出乎意料的结果(在这里,这样做了,调试xD很有趣(。

话虽如此,对于您的用例,我认为您最好使用简单的js过滤解决方案-它是最容易设置的-在后端,它是完全透明的,前端部分使用jQuery相当简单-它更用户友好,而且很容易工作。

最新更新