【问题标题】:What is the easy way to create django form创建django表单的简单方法是什么
【发布时间】:2016-01-19 07:17:02
【问题描述】:

例如我有 Student 模型

class Student(models.Model):
    first_name = models.CharField(max_lenght=100)
    last_name = models.CharField(max_lenght=100)
    learning_group = models.CharField(max_lenght=100)

所以我想为某个组中的每个学生创建以下表格:

|学生 |马克 |缺席 |

|约翰·史密斯 |输入标记 |输入缺勤时间|

感谢您的帮助。

编辑:

我将缺席和标记字段存储在 JSonField() 中,它看起来像这样
{ student_pk: 1, mark: 5,缺席: 3 }
那么我尝试了什么:

起初我尝试通过覆盖 forms.Form init 方法来实现这一点,但格式错误

def MarkBookForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.students = kwargs.pop('students', None)
        super(MarkBookForm, self).__init__(*args, **kwargs)
        for student in self.students:
            self.fields["student_{}".format(student.pk)] = forms.CharField(initial="{} {}".format(student.first_name, student.last_name)
            self.fields["mark_{}".format(student.pk)] = forms.FloatField()
            self.fields["absent_{}".format(student.pk)] = forms.FloatField()

这就是我想要的

这就是我所做的

【问题讨论】:

  • 请描述markabsent字段
  • 您尝试/研究了什么?表单在整个 django 文档中高度详细。
  • 是的,我试过但没有成功

标签: django django-forms


【解决方案1】:

首先你应该为markabsent定义你的模型 你可以这样使用(未测试:)):

models.py:

    class MyModel(models.Model):
        field1 = models.CharField(max_length=40, blank=False, null=False)
        field2 = models.CharField(max_length=60, blank=True, null=True)

forms.py:

    class FormForMyModel(forms.Form):
        form_field1 = forms.CharField(max_length=40, required=True)
        form_field2 = forms.CharField(max_length=60, required=False)

views.py:

    def create_a_my_model(request):
        if request.method == 'POST':
            form = FormForMyModel(request.POST)
            if form.is_valid():
                my_model = MyModel()
                my_model.field1 = form.cleaned_data.get('form_field1', 'default1')
                my_model.field2 = form.cleaned_data.get('form_field2', 'default2')
                my_model.save()
        else:        
            form = FormForMyModel()
        context_data = {'form': form}
        return HttpResponse('templtate.html', context_data)

以上示例概述了通用表单工作流程。

您可以在上面的示例中注意到两个烦人的问题:

  1. 我必须分别在MyModelFormForMyModel 上定义字段。然而,这两组(类型)的字段之间有很多相似之处,所以这是一种重复的工作。添加标签、验证器等时,相似性会增加。
  2. 创建MyModel 实例有点傻,必须手动分配所有这些值。

这就是 ModelForm 的用武之地。

那么回到两个问题:

  1. 我没有为每个模型字段定义一个表单字段,而是简单地在Meta 类中定义model = MyModel。这指示表单从模型字段自动生成表单字段。

  2. 模型表单具有可用的save 方法。这可用于在视图中的一行中创建模型实例,而不是逐个字段手动分配。

所以,让我们用ModelForm 来制作上面的例子:

models.py:

    class MyModel(models.Model):
        field1 = models.CharField(max_length=40, blank=False, null=False)
        field2 = models.CharField(max_length=60, blank=True, null=True)

forms.py:

    class MyModelForm(forms.ModelForm):  # extending ModelForm, not Form as before
        class Meta:
            model = MyModel

views.py:

    def create_a_my_model(request):
        if request.method == 'POST':
            form = MyModelForm(request.POST)
            if form.is_valid():
                # save the model to database, directly from the form:
                my_model = form.save()  # reference to my_model is often not needed at all, a simple form.save() is ok
                # alternatively:
                # my_model = form.save(commit=False)  # create model, but don't save to database
                # my.model.something = whatever  # if I need to do something before saving it
                # my.model.save()
        else:        
            form = MyModelForm()
        context_data = {'form': form}
        return HttpResponse('templtate.html', context_data)

【讨论】:

  • 我将删除我的答案,因为这比我的要全面得多。很好的答案。
猜你喜欢
  • 2014-01-28
  • 1970-01-01
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
相关资源
最近更新 更多