I just want to filter select field in a inlineformset.
Scenario:
Every task has own report.Each task has a booking .Booking has several booked items.I want to display only related bookeditems
based on booking in report form.Report form is generated using signals
and while editing i'm using inlineformset
to populate form with instances
.
Here is my code :
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>
I want to display only related bookeditems as choicefield in each report hoarding field .
I tried above code ,but no result.
You define your formset with the name formset
and customize the querysets for your fields properly here:
for form in formset:
form.fields['hoarding'].queryset = bookeditems.all()
But you then overwrite that formset
variable later in your view, removing the effects of that initial logic:
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)