首页 > 解决方案 > 基于模型在Django中手动制作自定义表单

问题描述

我正在制作一个基本的考勤记录系统,models.py文件中包含以下模型:Department, Employee, Absence.

Absence型号如下:

class Absences(models.Model):
    emp_id = models.ForeignKey(Employees, on_delete=models.CASCADE, null=False)
    leave_date = models.DateField(null=False)
    leave_type = models.ForeignKey(LeaveTypes, on_delete=models.CASCADE)
    absence_added = models.DateTimeField(auto_now_add=True)
    absence_updated = models.DateTimeField(auto_now=True)

现在我想创建一个表单,让您选择日期(将插入leave_date列中)和所有员工的列表,其中包含一个下拉列表(填充有leave_type)和提交按钮(一旦单击该按钮,根据Absences上面的模型将缺勤保存到数据库。

我该怎么做呢?

标签: pythondjango

解决方案


我找到了解决方案。

您可以通过简单地使用要插入模型表的值实例化模型类的对象,然后.save()在该对象上运行方法来直接插入模型。

我想制作一个可以在Absences模型中创建多个条目的表单(单个条目表单很容易使用CreateView类创建)。因此,我创建了一个模板,该模板包含输入字段,具体取决于Employees需要标记出勤的员工数量(来自模型)。以下是模板表单的代码。

     <form method="POST">
        {% csrf_token %}
        <label for="id_leave_date">Date</label>
        <input type="date" name="leave_date" class="form-control" placeholder="Select a date" required="" id="id_leave_date">
        <br>
        <table class="table table-hover">
            <thead>
                <tr>
                    <th>Employee</th>
                    <th>Absence</th>
                </tr>
            </thead>
            <tbody>
                {% for emp in emps %}
                <tr>
                    <td>{{ emp.emp_name }}</td>
                    <td>
                        <input type="radio" name="{{ emp.pk }}" id="p{{ emp.pk }}" value="present" checked> <label for="p{{ emp.pk }}">Present</label>
                        {% for leave in leaves %}
                        <input type="radio" name="{{ emp.pk }}" id="{{ leave.pk }}{{ emp.pk }}" value="{{ leave.pk }}"> <label for="{{ leave.pk }}{{ emp.pk }}">{{ leave.leave_type }}</label>
                        {% endfor %}
                    </td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
        <input type="submit" value="Mark Attendance" class="btn btn-primary">
    </form>

为了控制模板,我创建了一个视图called mark_all_attendance()GET如果通过请求访问该视图并发送生成表单所需的模板信息,此视图将显示上述模板。如果视图是通过POST请求访问的,它将通过遍历所有对来手动访问提交的表单字段的键值对来处理模板中提交的表单。在每次迭代中,它Absences使用提交的表单字段集实例化类的对象,然后.save()在该对象上运行该方法。这会将被迭代的字段集中的数据插入到Absences表中。然后使用 . 将浏览器重定向到成功页面HttpResponseRedirect。以下是视图代码:

`def mark_all_attendance(request):
submitted = False
all_emps = models.Employees.objects.all()
leaves = models.LeaveTypes.objects.all()
if request.method == 'POST':
    leave_date_from_post = datetime.datetime.strptime(request.POST['leave_date'], '%Y-%m-%d').date()
    print('Original: ', request.POST['leave_date'])
    print(leave_date_from_post)
    for key, value in request.POST.items():
        if not (key == 'csrfmiddlewaretoken' or  key == 'leave_date'):
            # print(key + " : " + value)
            if value != 'present': #if present, don't insert record in absences table
                record = models.Absences(
                    emp_id = models.Employees.objects.get(pk=key),
                    leave_type = models.LeaveTypes.objects.get(pk=value),
                    leave_date = leave_date_from_post
                    )
                record.save()
    return HttpResponseRedirect('/attendance/markallattendance?submitted=True')
else:
    if 'submitted' in request.GET:
        submitted = True
return render(request, 'attendance/markallattendance.html', {'emps': all_emps, 'leaves': leaves, 'submitted': submitted})`

推荐阅读