Dynamic Fields Form causing form tag to not render

Hi all,
I am relatively new to Django, having been thrown into it for a project, but have decent knowledge of other web languages. I am trying to create a form that contains dynamic fields based upon values in a database, in this case, for example, each new row in a certain table is a new field in the form. This all works fine, until I need to submit it. I noticed my view wasn’t running, and when I inspected the form in the browser, my tag did not render at all, despite me placing it a few layers outside of where the dynamic content is rendered. Can anyone help here? I am confident my views.py and urls.py are set up correctly, as all my static forms work fine.

HTML Code:

{% load static %}
{% load modal_tags %}
{% load humanize %}

{% csrf_token %}
{% block content %}

<div class="add_row_wrapper">
    <form method = "POST" action="{% url 'coreboard:add_row' %}">
        <div class="row_form_wrapper">
            {% csrf_token %}
            <div id="text" class="show_form input_div">
                {{ addRowForm.as_p }}
            </div>
        </div>
    </form>
</div>
{% endblock %}

forms.py Code

class AddRowForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super(AddRowForm, self).__init__(*args, **kwargs)
        
        # Query the database to get data
        data_from_db = Columns.objects.values()  # Example query, you can customize this

        # Process the data as needed
        for item in data_from_db:
            field_name = item["column_name"]
            field_type = item["column_type"]
            field_id = item["id"]
            required = item["required"]

            if field_type  == 'Text':
                field_class = forms.CharField
                widget = forms.TextInput(attrs={"class": "form-control"})
            elif field_type == 'Choice':
                field_class = forms.ChoiceField
                widget = forms.Choice(attrs={"class": "form-control"})
            elif field_type == 'DateTime':
                field_class = forms.DateTimeField
                widget = forms.DateTimeInput(attrs={"class": "form-control"})
            elif field_type == 'Person':
                field_class = forms.CharField
                widget = forms.TextInput(attrs={"class": "form-control"})
            elif field_type == 'Number':
                field_class = forms.DecimalField
                widget = forms.NumberInput(attrs={"class": "form-control"})
            elif field_type == 'YesNo':
                field_class = forms.BooleanField
                widget = forms.CheckboxInput(attrs={"class": "form-control"})
            elif field_type == 'Image':
                field_class = forms.CharField
                widget = forms.TextInput(attrs={"class": "form-control"})
            elif field_type == 'ProgressBar':
                field_class = forms.IntegerField
                widget = forms.NumberInput(attrs={"class": "form-control"})

            if field_type == 'Number':
                self.fields[f'field_{field_id}'] = field_class(
                        label=field_name,
                        required=required,  # Adjust as needed
                        widget=widget,
                        help_text=item["description"],
                        max_value=item["max_value"],
                        min_value=item["min_value"]
                    )
            else:
                self.fields[f'field_{field_id}'] = field_class(
                        label=field_name,
                        required=required,  # Adjust as needed
                        widget=widget,
                        help_text=item["description"]
                    )

Thanks!

Welcome @elliotcullen !

What does your view look like that is creating and rendering this form?

What have you looked at to verify that the form has been constructed correctly?

Good to be here!

I’m not entirely sure what you mean by constructed correctly, if you mean theoretically or if it functions - but I can see the form on my site, all the fields appear on my form visually. My views.py for this form is this:

@login_required
def add_row(request):
    print('running---------')

    if request.method == 'POST':
        form = AddRowForm(request.POST)
        if form.is_valid():
            print("Valid")
            for field_name in ['row_id', 'value', 'filter_on_value', 'column_id']:
                field_value = form.cleaned_data[field_name]
                print(field_value)
                # form.objects.create(**{field_name: field_value})
            form.save()
            return redirect('coreboard:coreboard')
    else:
        print("Not Valid")
        form = AddRowForm()
    return render(request, 'coreboard/coreboard.html', {'form': form})

It is not running at all, as the initial print statement does not execute.

Sorry I should mention - this is the rendering for the actual modal, the previous code is submission based. Keep in mind this is trimmed down by a lot - there are multiple other modals and functions in this view, hence why I have two separate views - one for rendering each modal and one for submission controls (if that makes sense…).

@login_required
def coreboard(request):
    context= {}
    addRowForm = AddRowForm()                    
    context['addRowForm'] = addRowForm

    return render(request, 'coreboard/coreboard.html', context)

I’m going by this;

By “tag”, I’m assuming you’re referring to your form.

So my question was asking what have you done to verify that the class AddRowForm() constructs a valid form object.

However, assuming that this is a valid form being created, you do have an issue that your view doesn’t match your template.

In your view, you have:

But in your template, you have:

These don’t match. The variable you’re trying to render doesn’t match the name of the variable that you are assigning in the context being rendered.

Sorry I should have clarified - see above for more clarification. When I say ‘tag’ I mean the form tag in my browser html. All the form fields render fine, but for some reason the form tag I use in my html to direct the action of submission seems to be getting overwritten/removed

There still seems to be quite a bit missing here from what you’re trying to do.

I’m getting the impression that you’re using some JavaScript to call these views and inject the responses into the page? We’ll need to see that.

Side note: When you’re posting files (or fragments), it’s helpful if you label each file with its directory and file name. (I have to guess that 'coreboard/coreboard.html' is the html fragment shown in your first post.)

It would be helpful here if you showed the html as it has been rendered, identifying how it is different from what you’re expecting.

No javascript being used - the views are called from urls.py (see below, at coreboard/urls.py)

import os

from django.urls import path, re_path, include
from django.conf import settings
from . import views

app_name = "coreboard"

urlpatterns = [
    path('', views.coreboard, name='coreboard'),
    path('dashboard/', views.dashboard, name='dashboard'),
    path('settings/',views.settings, name='settings'),
    path('add_text_column/', views.add_text_column, name='add_text_column'),
    path('add_choice_column/', views.add_choice_column, name='add_choice_column'),
    path('add_datetime_column/', views.add_datetime_column, name='add_datetime_column'),
    path('add_person_column/', views.add_person_column, name='add_person_column'),
    path('add_number_column/', views.add_number_column, name='add_number_column'),
    path('add_yesno_column/', views.add_yesno_column, name='add_yesno_column'),
    path('add_image_column/', views.add_image_column, name='add_image_column'),
    path('add_progressbar_column/', views.add_progressbar_column, name='add_progressbar_column'),
    path('add_row/', views.add_row, name='add_row')
    # path('addColumn/', views.add_column, name='addColumn')
]

The html I am expecting should look similar to this (taken from a working static form, viewed in dev tools - couldnt select multiple lines to copy sorry). This html template displays a modal with many different forms, but only one at a time - essentially it is allowing the user to create columns in a table - each form is a different column type.
The part I am missing is the form tag in red, wrapped around other html elements and the generated fields.

However, what I currently receive is this:
See next reply
Note the lack of a form tag, even though I have explicitly defined it in my html template 2 layers outside the generated django content, here:

{% load static %}
{% load modal_tags %}
{% load humanize %}

{% csrf_token %}
{% block content %}

<div class="add_row_wrapper">
    <form method = "POST" action="{% url 'coreboard:add_row' %}">
        <div class="row_form_wrapper">
            <div id="text" class="show_form input_div">
                {{ addRowForm.as_p }}
            </div>
        </div>
    </form>
</div>
{% endblock %}

A little more information - the modal is being called from the main html, as such:

{% modalform id='addRow' title='Add Row' submit_text='Add' enctype='POST'%}
    {% csrf_token %}
    {% include "../coreboard/modals/addRow.html" %}
{% endmodalform %}

I apoligise if I am not making sense - I didn’t start this project and I have been trying to unravel using django for the first time, so may have done something wrong.

HTML from dynamic form, as I cannot embed two images

The two are not related. The JavaScript would be run in the browser, URL resolution occurs in the server.

Additionally, in your second image, I see a script element referencing an addRow.js file, which does reinforce the idea that you’ve got some JavaScript involved here.

Finally, please try to avoid posting images of text. When necessary, copy/paste the actual HTML into your post.