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

How to dynamically filter ModelChoice's queryset in a Inlineformset?

我只想过滤内联表单集中的 select 字段。

场景:

每个任务都有自己的report.Each任务有预订。预订有几个预订items.I只想显示相关bookeditems基于报告form.Report表格中的预订使用 signals 生成,在编辑时我使用 inlineformsetinstances.

填充表单

这是我的代码:

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>

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

我试过上面的代码,但是没有结果。

您使用名称 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)