Another basic question I'm afraid which I'm struggling with. I've been through the various Django documentation pages and also search this site. The only thing I have found on here was back in 2013 which suggested setting up a custom filter template.
Anyhow, I'm trying to generate my own form instead of using Django's own way of generating it through {{ form }}. This is simply so I can control the way the form is presented.
I've worked out various ways to access the required information such as (within my for item in form loop);
I'm trying to identify the item type so I can use the correct input type, however I'm struggling to workout what item.xxxx should be. Since this is correctly displayed through {{ form }} I am making an assumption that this information is available somewhere in the form, just struggling to find out how to access it so I can identify the correct input type. I'm doing this manually so I can use the correct Bootstrap styles to display the input fields.
Any assistance would be appreciated (or just pointing in the right direction). I'm very new to this so apologies for my very basic questions, its difficult without knowing someone I can just go an ask these questions to.
Regards
Wayne
Not sure if you need it but here is some code;
Form:
class NewsForm(ModelForm):
class Meta:
model = News_Article
exclude = ('news_datetime_submitted', 'news_yearmonth', )
labels = {
'news_title': _('Enter News Title'),
}
help_texts = {
'news_title': _('Enter a title to give a short description of what the news is.'),
}
error_messages = {
'news_title': {
'max_length': _("News title is too long."),
},
}
View (not worked on the POST bit yet, this is just what's from the Django documentation, POST is my next thing to work out)
def create(request, dataset):
if dataset not in ['news', 'announcement']:
return HttpResponseRedirect(reverse('pages'))
rDict = {}
if request.method == 'POST':
if dataset == "news":
form = NewsForm(request.POST)
elif dataset == "announcement":
form = AnnouncementForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/home/')
else:
pass
else:
announcement = get_announcement()
if not announcement == None:
rDict['announcement'] = announcement
if dataset == "news":
rDict['form'] = NewsForm()
rDict['branding'] = {'heading': 'Create News Item', 'breadcrumb': 'Create News', 'dataset': 'create/' + dataset + '/'}
elif dataset == "announcement":
rDict['form'] = AnnouncementForm()
rDict['branding'] = {'heading': 'Create Announcement', 'breadcrumb': 'Create Announcement', 'dataset': 'create/' + dataset + '/'}
rDict['sitenav'] = clean_url(request.path, ['"', "'"])
rDict['menu'] = Menu.objects.all().order_by('menu_position')
# pdb.set_trace()
return render(request, 'en/public/admin/admin_create.html', rDict)
Template code
<form action="/siteadmin/{{ branding.dataset }}" method="post">
{% csrf_token %}
{% for item in form %}
<div class="row">
<div class="col-xs-2 col-md-2">
</div>
<div class="col-xs-4 col-md-4">
<div class="panel-title pull-right">
{% if item.help_text %}
<img src="/static/images/info.png" height="20" width="20" aria-hidden="true" data-toggle="popover" title="{{ item.help_text }}"> 
{% endif %}
{{ item.label_tag }}
</div>
</div>
<div class="col-xs-4 col-md-4">
<div class="input-group">
<input type="{{ item.widget }}" class="form-control" placeholder="" aria-describedby="{{ item.id_for_label }}">
</div>
</div>
<div class="col-xs-2 col-md-2">
{% if forloop.last %}
<input type="submit" value="Submit" />
{% endif %}
</div>
</div>
{% endfor %}
</form>
CharField() is a Django form field that takes in a text input. It has the default widget TextInput, the equivalent of rendering the HTML code <input type="text" ...> .
{{ form.as_p }} – Render Django Forms as paragraph. {{ form.as_ul }} – Render Django Forms as list.
cleaned_data returns a dictionary of validated form input fields and their values, where string primary keys are returned as objects. form. data returns a dictionary of un-validated form input fields and their values in string format (i.e. not objects).
CharField is a string field, for small- to large-sized strings. It is like a string field in C/C+++. CharField is generally used for storing small strings like first name, last name, etc. To store larger text TextField is used. The default form widget for this field is TextInput.
Try this:
<input type="{{ item.field.widget.input_type }}" ...
No link to docs, found it by using debugger (not the best practice, I know...)
As per @Smurf's comment, this won't work for all widgets, like Select
, CheckBox
, any MultiWidget
, etc... Seems to only work for text input and its variants (password, email...)
A better solution is to create custom widgets and render your form fields in template as usual. You can set any custom attributes there, see https://docs.djangoproject.com/en/1.8/ref/forms/widgets/#customizing-widget-instances
If you absolutely have to modify widgets in the template, then use django-widget-tweaks
This app provides a nice-looking form filters to alter widgets (i.e. their attributes). But be aware that it does so by way of string mongering with the already-rendered HTML ("rendered" as concernes the Widget
instance).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With