没有初始数据的 Django 表单集
Django formset with no initial data
我是 Django 菜鸟,我正在开发一个小应用程序来注册时间(持续时间)和每个用户每天的活动量。有点像工作日志。我的问题是:我的“添加条目”视图显示并更新旧记录,而不是向数据库添加新记录。我需要一个视图来添加新记录,而不是替换旧记录。
通过在#django IRC 频道四处搜索,我了解到默认情况下 formset-way 会利用旧数据,而不是设置客户端以添加新数据。但是,我没有找到任何关于如何避免这种行为并让客户为 "appending new data" 而不是 "editing existing data" 提供空白表格的信息。
我的截止日期真的临近了,非常感谢所有帮助。
以下是相关的代码片段:
来自models.py
class Activity(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
class Workday(models.Model):
entrydate = models.DateField()
worker = models.ForeignKey(User, on_delete=models.CASCADE)
class Entry(models.Model):
duration = models.DurationField()
quantity = models.PositiveIntegerField()
activity = models.ForeignKey(Activity, on_delete=models.CASCADE)
workday = models.ForeignKey(Workday, on_delete=models.CASCADE)
来自forms.py
class EntryForm(ModelForm):
activity = ModelChoiceField(queryset=Activity.objects.order_by('name'), initial=0)
class Meta:
model = Entry
fields = ['activity',
'duration',
'quantity',
]
class WorkdayForm(ModelForm):
class Meta:
model = Workday
fields = ['entrydate']
widgets = {'entrydate': SelectDateWidget}
来自views.py
def addentry(request):
EntryFormSet = modelformset_factory(Entry, form=EntryForm, extra=0, fields=('activity', 'duration', 'quantity'))
if request.method == 'POST':
workdayform = WorkdayForm(request.POST, prefix='workday')
formset = EntryFormSet(request.POST)
if formset.is_valid() and workdayform.is_valid():
# Generate a workday object
workday = workdayform.save(commit=False)
workday.entrydate = workdayform.cleaned_data['entrydate']
workday.worker = request.user
workday.save()
# Generate entry objects for each form in the entry formset
for form in formset:
e = form.save(commit=False)
e.workday = workday
e.save()
form.save_m2m()
messages.add_message(request, messages.SUCCESS,
"Registrert aktivitet " +
e.workday.entrydate.strftime('%A %d. %B %Y') +
": " + e.activity.name + " (" + str(e.quantity) +") - " +
str(e.duration)
)
return redirect('index')
else:
workdayform = WorkdayForm(request.POST, prefix='workday')
formset = EntryFormSet(request.POST)
for dict in formset.errors:
messages.add_message(request, messages.ERROR, dict)
context = {
'workdayform': workdayform,
'formset': formset,
}
return render(request, 'register/addentry.html', context)
else:
workdayform = WorkdayForm(prefix='workday')
formset = EntryFormSet()
context = {
'workdayform': workdayform,
'formset': formset,
}
return render(request, 'register/addentry.html', context)
来自addentry.html
{% block content %}
{% if user.is_authenticated %}
<h1>Ny dag</h1>
{% if formset and workdayform %}
<form id="newdayform" method="POST" class="post-form">
{% csrf_token %}
{{ workdayform.as_p }}
{{ formset.management_form }}
<table>
<thead>
<tr>
<td>Aktivitet</td>
<td>Varighet<br/>(HH:MM:SS)</td>
<td>Antall</td>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr>
<td>{{ form.activity }}</td>
<td>{{ form.duration }}</td>
<td>{{ form.quantity }}</td>
<td class="hidden">{{ form.id }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit">Registrer tid</button>
</form>
<script src="{% static 'register/jquery.formset.js' %}"></script>
<script type="text/javascript">
$(function() {
$('#newdayform tbody tr').formset();
})
</script>
{% if entryform.errors or workdayform.errors %}
<h3>Feil i utfyllingen</h3>
{{ entryform.errors }}
{{ workdayform.errors }}
{% endif %}
{% else %}
<p>No form!</p>
{% endif %}
{% endif %}
{% endblock %}
感谢@e4c5 和 this previous Q&A,通过将没有对象的查询集传递给表单集解决了这个问题,如下所示:
def addentry(request):
(...)
qs = Entry.objects.none()
formset = EntryFormSet(queryset=qs)
(...)
我是 Django 菜鸟,我正在开发一个小应用程序来注册时间(持续时间)和每个用户每天的活动量。有点像工作日志。我的问题是:我的“添加条目”视图显示并更新旧记录,而不是向数据库添加新记录。我需要一个视图来添加新记录,而不是替换旧记录。
通过在#django IRC 频道四处搜索,我了解到默认情况下 formset-way 会利用旧数据,而不是设置客户端以添加新数据。但是,我没有找到任何关于如何避免这种行为并让客户为 "appending new data" 而不是 "editing existing data" 提供空白表格的信息。
我的截止日期真的临近了,非常感谢所有帮助。
以下是相关的代码片段:
来自models.py
class Activity(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
class Workday(models.Model):
entrydate = models.DateField()
worker = models.ForeignKey(User, on_delete=models.CASCADE)
class Entry(models.Model):
duration = models.DurationField()
quantity = models.PositiveIntegerField()
activity = models.ForeignKey(Activity, on_delete=models.CASCADE)
workday = models.ForeignKey(Workday, on_delete=models.CASCADE)
来自forms.py
class EntryForm(ModelForm):
activity = ModelChoiceField(queryset=Activity.objects.order_by('name'), initial=0)
class Meta:
model = Entry
fields = ['activity',
'duration',
'quantity',
]
class WorkdayForm(ModelForm):
class Meta:
model = Workday
fields = ['entrydate']
widgets = {'entrydate': SelectDateWidget}
来自views.py
def addentry(request):
EntryFormSet = modelformset_factory(Entry, form=EntryForm, extra=0, fields=('activity', 'duration', 'quantity'))
if request.method == 'POST':
workdayform = WorkdayForm(request.POST, prefix='workday')
formset = EntryFormSet(request.POST)
if formset.is_valid() and workdayform.is_valid():
# Generate a workday object
workday = workdayform.save(commit=False)
workday.entrydate = workdayform.cleaned_data['entrydate']
workday.worker = request.user
workday.save()
# Generate entry objects for each form in the entry formset
for form in formset:
e = form.save(commit=False)
e.workday = workday
e.save()
form.save_m2m()
messages.add_message(request, messages.SUCCESS,
"Registrert aktivitet " +
e.workday.entrydate.strftime('%A %d. %B %Y') +
": " + e.activity.name + " (" + str(e.quantity) +") - " +
str(e.duration)
)
return redirect('index')
else:
workdayform = WorkdayForm(request.POST, prefix='workday')
formset = EntryFormSet(request.POST)
for dict in formset.errors:
messages.add_message(request, messages.ERROR, dict)
context = {
'workdayform': workdayform,
'formset': formset,
}
return render(request, 'register/addentry.html', context)
else:
workdayform = WorkdayForm(prefix='workday')
formset = EntryFormSet()
context = {
'workdayform': workdayform,
'formset': formset,
}
return render(request, 'register/addentry.html', context)
来自addentry.html
{% block content %}
{% if user.is_authenticated %}
<h1>Ny dag</h1>
{% if formset and workdayform %}
<form id="newdayform" method="POST" class="post-form">
{% csrf_token %}
{{ workdayform.as_p }}
{{ formset.management_form }}
<table>
<thead>
<tr>
<td>Aktivitet</td>
<td>Varighet<br/>(HH:MM:SS)</td>
<td>Antall</td>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr>
<td>{{ form.activity }}</td>
<td>{{ form.duration }}</td>
<td>{{ form.quantity }}</td>
<td class="hidden">{{ form.id }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit">Registrer tid</button>
</form>
<script src="{% static 'register/jquery.formset.js' %}"></script>
<script type="text/javascript">
$(function() {
$('#newdayform tbody tr').formset();
})
</script>
{% if entryform.errors or workdayform.errors %}
<h3>Feil i utfyllingen</h3>
{{ entryform.errors }}
{{ workdayform.errors }}
{% endif %}
{% else %}
<p>No form!</p>
{% endif %}
{% endif %}
{% endblock %}
感谢@e4c5 和 this previous Q&A,通过将没有对象的查询集传递给表单集解决了这个问题,如下所示:
def addentry(request):
(...)
qs = Entry.objects.none()
formset = EntryFormSet(queryset=qs)
(...)