Reputation: 734
<here all loading of static , template_filters, crispy_forms >
<form>
{% for i in artifact_length %}
{% with artifact_name="artifact"|artifact_name:forloop.counter0 %}
{{form.artifact_name|as_crispy_field}}
{% endwith %}
{%endfor%}
</form>
This is related template code. Here i want to render form fields with names artifact_0
, artifact_1
as coming from form. The variable artifact_name
inside with
is working fine and returning expected identifiers artifact_0
, artifact_1
, but i want to use these variables as form fields to render as as_crispy_field
.
The code {{form.artifact_name|as_crispy_field}}
does not print anything because it is assuming form as field with name artifact_name
which is not. Instead i want to use the value of variable here.
forms.py
class Someform(forms.form):
def __init__(self, artifact_obj):
super().__init__()
count = 0
for artifact in artifact_obj:
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
count += 1
tags.py
@register.filter('artifact_name')
def get_artifact_name(artifact_prefix: str, counter: int):
print('method', 'prefix', artifact_prefix, 'counter', counter)
return f'{artifact_prefix}_{counter}'
There is variable length form being created. As informs.py
form fields are being created with artifact_count
where count can range from 0 to len of obj.
Upvotes: 1
Views: 566
Reputation: 21787
You don't need to use filters / template tags, etc. for this purpose. The simplest solution would be to loop over the form fields to render them:
<form>
{% for field in form %}
{{ field|as_crispy_field }}
{%endfor%}
</form>
This will loop over all the fields in your form.
If you particularly care about the order of these fields you can call the forms order_fields
method:
class Someform(forms.form):
def __init__(self, artifact_obj, *args, **kwargs):
super().__init__(*args, **kwargs)
for count, artifact in enumerate(artifact_obj):
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
self.order_fields(["field_1", "field_2", ...] + [f"artifact_{i}" for i, _ in enumerate(artifact_obj)] + [..., "field_n"])
If you particularly want to render the other fields separately you can add a method to your form that will allow you to loop over these fields:
class Someform(forms.form):
def __init__(self, artifact_obj, *args, **kwargs):
super().__init__(*args, **kwargs)
for count, artifact in enumerate(artifact_obj):
self.fields[f'artifact_{count}'] = forms.CharField(widget=forms.NumberInput())
self.artifact_length = len(artifact_obj)
def artifact_fields(self):
return [self[f'artifact_{i}'] for i in range(self.artifact_length)]
And then loop over these in the template:
<form>
{% for field in form.artifact_fields %}
{{ field|as_crispy_field }}
{%endfor%}
</form>
Upvotes: 1