Accessings fields directly in Django adminform template? - django

I have a ton of fields that I need to layout (reorder) in a specific way the form (with some other extra html stuff). I created change_form.html file for my model, which itself works.
The problem is all examples are looping over the fields, I just want to refer to each field by name.
# this works
{% for fieldset in adminform %}
{% for line in fieldset %}
{% for field in line %}
<p>{{ field.field }}</p>
{% endfor %}
{% endfor %}
{% endfor %}
I know you can customise the admin.ModelAdmin with fieldsets, etc.. But that's not what I want.
I was trying different ways like below, but it doesn't work:
# assuming the admin model has the fields: first_name & last_name
{% block content %}
<!-- doesn't work !!! ->
{{ adminform.fieldsets.0.1.fields.first_name.field }}
{{ adminform.fieldsets.0.1.fields.last_name.field }}
<!-- neither does this -->
{{ adminform.fields.first_name.field }}
{{ adminform.fields.last_name.field }}
{% endblock %}
Now this doesn't work, is there any efficient way to directly access the fields I need?

I was looking in the complete wrong direction. Its actually super simple, you can use it as follows.
When you have model with a field last_name you can access the field:
# change_form.html (custom)
{% extends "admin/change_form.html" %}
{% block field_sets %}
# get the label
<label for="{{ adminform.form.last_name.label }}">
{{ adminform.form.last_name.id_for_label }}
</label>
# get the html widget
{{ adminform.form.last_name }}
# get the field value
{{ adminform.form.last_name.value }}
# create your own input (without the label)
<input name="{{ adminform.form.last_name.html_name }}">
# some other fields you can reference
{{ adminform.form.last_name.max_length }}
{{ adminform.form.last_name.required }}
{{ adminform.form.last_name.help_text }}
{{ adminform.form.last_name.label_suffix }}
{% endblock %}

U can create a ModelForm to be used in your ModelAdmin, check de docs -> https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form
another way could be setting fields tuple, docs here -> https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fields
Hope this drives U in the right path.

Related

What is form.visible_fields in Django and how do I index into it?

Sometimes I have the need to render a particular Django form field in a particular way. I would like to be able to access this field and only this field in order to customize its rendering in my template.
I know, for example, that I can do something like this:
<!--Access the form field at index 2-->
{% for field in form.visible_fields %}
{% if forloop.counter == 2 %}
<!--Render my form field the way that I want to-->
{% endif %}
{% endfor %}
Intuitively, I would expect to be able to do something like {{ form.visible_fields[2] }} or perhaps {{ form.visible_fields['field_name'] }}.
Unfortunately, my various attempts at the above have all failed and so I'm left wondering if this is possible. Any advice?
According to Django documentation you should be able to something like this:
{# Include the hidden fields #}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}

Django accessing form fields dynamically in template

I am trying to mimic the django admin's fieldsets functionality, to group form fields in my own view.
So I have a form in my template, and I have passed the fieldset list in my context data.
{% for fieldset in fieldsets %}
<fieldset class="module aligned">
<h2>{{ fieldset.0 }}<h2>
{% for field in fieldset.1.fields %}
<div>
{{ form.field }}
</div>
{% endfor %}
</fieldset>
{% endfor %}
The problem is the {{ form.field }} is treating field as a string, and not as the value stored in the variable. Is there a way to access this in the template, like getattr().

django templates: How to know form field type and add any buttons based on field type

I am displaying my django forms dynamically with below code.
{% for field in form %}
{% if field.field.required %}
<span class="red">*</span>
{% endif %}
{{ field.label }}:
{{ field }}
{% endfor %}
Now I want to know the datatype of fields.if field type is Datetimeinput then I want give one button beside to it to get JavaScript calender.
i want do like as below but I am not able get it
{% for field in form %}
{% if field.field.required %}
<span class="red">*</span>
{% endif %}
{% if field.field_type == 'Datetimeinput' %}
{{ field.label }}:
{{ field }}
<label>From :</label><input type="text" name="from1" class="txtbox"><input type="button" value="Cal" onclick="displayCalendar(document.forms[0].from1,'yyyy-mm-dd',this)">
{% else %}
{{ field.label }}:
{{ field }}
{% endif %}
{% endfor %}
Help me out thanks in advance.
Make a template tag. Depending on Get type of Django form widget from within template. I used this solution once or twice.
from django import template
register = template.Library()
#register.filter('klass')
def klass(ob):
return ob.__class__.__name__
In template:
{{ field.field.widget|klass }}
Will return field class name to be used in your if statements.
You could write a custom template filter for that.
#register.filter
def fieldtype(obj):
return obj.__class__.__name__
Docs on custom filters: link
However, why not just render fields without looping over them?
{{ form.birthdate }}
Then you'll know for sure what is what.

Django: For Loop to Iterate Form Fields

I don't want to use django's built in form generation, seeking to specify each field in my template in order to customize the html output.
How do I iterate over a series of form fields?
If my form looks like this:
class MyForm(forms.Form):
main_image = forms.ImageField()
second_image = forms.ImageField()
third_image = forms.ImageField()
fourth_image = forms.ImageField()
...
Is there way to write a {% for %} loop so that I can iterate through:
{{ form.main_image }}
{{ form.second_image }}
{{ form.third_image }}
{{ form.fourth_image }}
I tried the following which seemed logical, but did not work:
{% for field in form %}
{{ form.field }}
{% endfor %}
Well this would clearly not work:
{% for field in form %}
{{ form.field }}
{% endfor %}
but this will:
{% for field in form %}
{{ field }}
{% endfor %}
The best way is to use two loops, one for hidden fields and one for visible fields :
visibles:
{% for field in form.visible_fields %}
{{ field.label }}
{{ field }}
{% endfor %}
hiddens:
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
in this way you will have better control over UI elements.
This one should work :
{% for field in form %}
{{ field }}
{% endfor %}
Once you loop through field in form , you can't access form.field
For any frontend developers looking to customize a Django form you can use a package called django-widget-tweaks to render fields individually. Example code below:
{# Your template with the form #}
{% extends "base.html" %}
{% load widget_tweaks %}
<form action="" method="POST">
{% csrf_token %}
{% for field in form %}
<label for="{{ field.id_for_label }}">
{{ field.label }}{% if field.field.required %}*{% endif %}
</label>
{% render_field field %}
{% endfor %}
<button type="button">
Submit Form
</button>
</form>
Note: You'll want to make this look nicer of course, and you may want to loop through your form errors if there are any.
They have some very useful examples on their PyPi page as well.

django change form field in .html template output

I create a form based on a model , like seen below:
class ContactSelectionForm(forms.ModelForm):
contacts = ManyToManyByLetter(Contact, field_name="first_name")
class Meta:
model = ContactSelection
exclude = ('created_by',)
When I process this view I see at the .html output a field labeled with "Contact".
Now I`m wondering whether it is possible to change this output. For example I want to name this field not "Contact" but "Selected Contacts".
This is the form processing part of the .html template:
<form action="{{ request.path }}" method="POST">
<div>
<fieldset class="module aligned">
{% for field in form.visible_fields %}
<div class="form-row">
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
<p><input type="submit" value="Save" /></p>
</fieldset>
</div>
</form>
If somebody is wondering what ManyToManyByLetter(Contact, field_name="first_name") in the form is, check out http://code.google.com/p/django-ajax-filtered-fields/ . A very helpful many2many javascript library.
Did you try setting the fields label?
(the docs)
contacts = ManyToManyByLetter(Contact, field_name="first_name", label="Selected Contacts")