Skip to main content
 首页 » 编程设计

python之没有初始数据的 Django 表单集

2024年09月07日33jyk

我是 Django 菜鸟,我正在开发一个小应用程序来记录每个用户每天的时间(持续时间)和事件量。有点像工作日志。我的问题是:我的“添加条目” View 显示并更新旧记录,而不是向数据库添加新记录。我需要一个 View 来添加新记录,而不是替换旧记录。

通过在#django IRC channel 四处搜索,我了解到默认情况下,formset-way 会利用旧数据,而不是设置客户端以添加新数据。但是,我没有找到任何关于如何避免这种行为并让客户提供空白表格以“附加新数据”而不是“编辑现有数据”的信息。

我的截止日期真的临近了,非常感谢所有帮助。

以下是相关的代码片段:

来自 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) 
 
   (...)