没有初始数据的 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)

   (...)