modelform display table of filtered data

I have a modelform and I want to do two things. Filter the modelform data where the field I want input form the user but I want to show all the data in a table.

forms.py

class MyForm(forms.ModelForm):
    class Meta:   
        model = MyModel
        fields = ["input_field"]

views.py

def my_view(request):
    context = {}
    form = ""
    data = ""
    if request.POST:
        form = MyForm(request.POST)
        data = *this is where I think to filter data*
        if form.is_valid():
            obj = form.save(commit=True)
            obj.save()
    else:
        form = MyForm()
        data = *this is where I think to filter data*

     context['form'] = form
     context['data'] = data  
     return render(request, 'template.html', context)

And the template to loop through the table is done just so. Each row the user should be able to set a value and then post those values back to the database.

template.html

   <h1>Unassigned Data</h1>
    <form action = "" method = "post">
      <input type="submit" value="Submit">
      <table>
        <tr>
          <th>Field 1</th>
          <th>Input Field</th>
          <th>Field 2</th>
        </tr>
        {% for field in data %}
        <tr>
          <td>{{ field.field1 }}</td>
          {% csrf_token %}
          <td>{{ form.input_field }}</td>
          <td>{{ field.field2 }}</td>
        </tr>
        {% endfor %}
      </table>
    </form>

So, I need to filter the data where the input field is blank. Show that data in a table, and then the user can then enter data for the row they want. I can get table to show if I set up a query that filters the table and then passes it but the query is technically not tied to the data that the modelform has.

So, originally, I had in the view outside of the if statement:

      data = MyModel.objects.filter(input_field__exact="")

But if notice in the forms.py that I set the model to MyModel. How do I set model in forms.py to the table data filtered to input_field is empty, and then display the table for input?

And do I have the right way of posting that back?

Maybe you can use queryset inside form constructor which look something like this:

class MyForm(forms.ModelForm):
    class Meta:   
        model = MyModel
        fields = ["input_field"]
   
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields["input_field"].queryset = MyModel.object.filter(input_field__exact="")

I don’t know if the prior response answered your question or not - but I do have a couple of really minor things I’ll mention.

  • It looks like you’re rendering the csrf_token with every row - that’s not necessary, it only needs to be rendered once for the form.

  • I personally find your use of the name field here to reference a row of data confusing - others are likely to as well, since the common usage of that name is to refer to an individual data element and not an entire row.

  • You’re creating one instance of the form, but rendering that same form on every row in data. Since it’s the same form on every row, you’ll only get one element returned - and, I don’t believe you’re going to get any information associating the data being entered with the row that it was entered on.
    If the user is only going to be entering one value, then you might be able to make this work for you by adding some kind of row-id to the form. Otherwise, what you need to be doing here is creating a separate form for each row. (Take a look at formsets.)