如何在Inlineformset中动态过滤ModelChoice的查询集?

时间:2017-11-02 11:58:40

标签: django django-forms django-templates django-views inline-formset

我只是想在inlineformset中过滤选择字段。

情景:

每个任务都有自己的报告。每个任务都有一个预订.Booking有几个预订的项目。我想在报告表格中仅根据预订显示相关的bookeditems。报告表格是使用signals和在编辑时我正在使用inlineformset使用instances填充表单。

这是我的代码:

Models.py

class Task(models.Model):

    booking = models.ForeignKey(
        Booking, blank=False, null=True, related_name='booking_id',)
    ......


class Report(models.Model):

    task = models.ForeignKey(
        Task, blank=True, null=True, related_name='task',)

    hoarding = models.OneToOneField(
        BookedItem, blank=True, null=True, related_name='+')

    status = models.CharField(
        max_length=32, choices=ReportStatus.CHOICES, blank=True, null=True, default=ReportStatus.INCOMPLETE)

views.py

def report(request, pk):
    task_instance = get_object_or_404(Task, pk=pk)
    booking = task_instance.booking_id
    #all bookeditems here
    bookeditems = BookedItem.objects.filter(Booking_id=bookeditem)

     # inline formsetfactory
    ReportFormset = inlineformset_factory(Task,Report,form=TaskReportForm,fields=('hoarding','status',), extra=0,can_delete=False,)
    data = request.POST or None
    formset = ReportFormset(instance=task_instance)
    for form in formset:
                form.fields['hoarding'].queryset = bookeditems.all()

    if request.method == 'POST':
        formset = ReportFormset(request.POST,instance=task_instance)
        if formset.is_valid():
            formset.save
            return redirect('taskreport')
        else:
             formset = ReportFormset(instance=task_instance)    
    else:
        formset = ReportFormset(instance=task_instance)
    return render(request, 'report.html', {'formset': formset,
                                                       'bookeditems': bookeditems,
                                                       'task_instance': task_instance})

forms.py

class TaskReportForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(TaskReportForm, self).__init__(*args, **kwargs)
    class Meta:
        model = PrinterReport
        fields = ['hoarding','status',]
        exclude = ['printer_task',]

report.html:

<form action="." method="POST">{% csrf_token %}
      {{ formset.management_form }}

           <section id="account" class="nice-padding active">
                              <div class="link-formset">
                                <table class="listing listing-page">
                                          <thead>
                                            {% for form in formset %}
                                                {% if forloop.first %}
                                                    {% for field in form %}
                                                        <th>{{ field.label_tag }}</th>
                                                    {% endfor %}
                                                {% endif %}
                                          </thead>
                                          <tbody>
                                                <tr>
                                                    {% for field in form %}
                                                        <td>{{ field }}</td>
                                                    {% endfor %}
                                                </tr>
                                            {% endfor %}
                                          </tbody>
                                      </table>
                              </div>            

                  </section>

                   <li class="">
                        <input type="submit" value="Save" class="button">
                    </li>

                            </ul>
                        </fieldset>
</form>

我想在每个报告囤积栏中仅显示相关的预订项目作为选择字段。

我尝试了上面的代码,但没有结果。

1 个答案:

答案 0 :(得分:1)

您使用名称formset定义您的formset,并在此处正确自定义字段的查询集:

for form in formset:
    form.fields['hoarding'].queryset = bookeditems.all()

但是您稍后会在视图中覆盖该formset变量,从而消除该初始逻辑的影响:

if request.method == 'POST':
        formset = ReportFormset(request.POST,instance=task_instance)
        if formset.is_valid():
            formset.save
            return redirect('taskreport')
        else:
             #invaild form, re-render with errors - and no custom querysets
             formset = ReportFormset(instance=task_instance)    
    else:
        #non-POST request, render form - again overwriting custom querysets
        formset = ReportFormset(instance=task_instance)