How to customize the input element generated by django.forms? - django

I'm using django.forms to generate my login/signup page, part of code is as follows:
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
{# username is directed to email field in our model #}
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login" />
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% else %}
<input type="hidden" name="next" value="{% url 'home' %}" />
{% endif %}
</form>
As you can see, the {{ form.username }} and {{ form.password }} will automatically generate an <input id="id_username" maxlength="254" name="username" type="text"> and an <input id="id_password" name="password" type="password"> respectively. But I want to add some extra attributes to these input fields, like placeholderand class. Where can I customize these?

Either manually:
<input type="text" name="{{ form.field.html_name }}" placeholder="foo" value="{{ form.field.value }}" />
Or via the widget attrs argument
https://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs
class MyForm(forms.Form):
field = forms.CharField(widget=forms.TextInput(attrs={'placehoder': 'foo', 'title': 'baz'}))

You may use django-widget-tweaks which is a very nice library for tweaking django's widget. I've used it and it's quite simple.
From their site:
{% load widget_tweaks %}
<!-- change input type (e.g. to HTML5) -->
{% render_field form.search_query type="search" %}
<!-- add/change several attributes -->
{% render_field form.text rows="20" cols="20" title="Hello, world!" %}
<!-- append to an attribute -->
{% render_field form.title class+="css_class_1 css_class_2" %}
<!-- template variables can be used as attribute values -->
{% render_field form.text placeholder=form.text.label %}
Hope this helps!

Related

How to display uploaded pdf file along with machine name and operation number based on select from dropdown

In this project, I want to display machine name and operation number along with uploaded pdf files based on select machine name and operation number from dropdown menu. This project is working but when I add and select another file in same machine name and operation number, it is displaying two pdf files along with previous pdf file of another machine name and operation number, exactly I don't want it. It should display machine name and operation number along with uploaded pdf file based on select from dropdown menu. And also when I upload another pdf files in same machine name and operation number, it should display two pdf files along with same machine name and operation number within same row.
This project is working fine but I want above validations.
Please anyone can help me out, this will be great for me. Please..
views.py:
def upload(request):
controlmachines = Controlmachine.objects.all()
return render(request,'usermaster/upload.html',{'machines':machines})
def save_machine(request):
if request.method == "POST":
machine_name = request.POST.get('machinename', '')
operation_no = request.POST.get('operationname','')
choiced_cmachine = Controlmachine.objects.filter(machine_name=machine_name, operation_no=operation_no)
cmachines = Controlmachine.objects.all()
return render(request,'usermaster/upload.html',{'machines':machines,'choiced_cmachine':choiced_cmachine})
def index(request):
if request.method == 'POST':
form = ControlmachineForm(request.POST, request.FILES)
if form.is_valid():
model_instance = form.save()
model_instance.save()
else:
form = ControlmachineForm()
controlmachiness = Controlmachine.objects.all()
return render(request,'usermaster/upload_file.html',{'form':form,'controlmachiness':controlmachiness})
upload.html:
<form action="{% url 'save_machine' %}" method="post">
{% csrf_token %}
<label for="machinename">Select Machine Name:</label>
<select name="machinename" id="machinename">
{% for machine in cmachines %}
<option value="{{ machine.machine_name }}">{{ machine.machine_name }}</option>
{% endfor %}
</select>
<br>
<br>
<label for="operationname">Select Operation Number:</label>
<select id="operationname" name="operationname">
{% for machine in cmachines %}
<option value="{{ machine.operation_no }}">{{ machine.operation_no }}</option>
{% endfor %}
</select>
<br>
<br>
<br>
<input type="submit" value="Save">
</form>
<tr>
{% for choice in choiced_cmachine %}
<td>{{choice.machine_name}}</td>
<td>{{choice.operation_no}}</td>
<td>
{% for file in controlmachines %}
view file
{% endfor %}
</td>
{% endfor %}
</tr>
control_uploadfile.html:
<html>
<head>
<title>Master File Upload</title>
</head>
<body>
<p><h1>Control File Upload</h1></p>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button> <br><br>
</form>
</body>
</html>
control_show.html:
{% extends "master/control_base.html" %}
{% block title %}Control File{% endblock title %}
{% block content %}
<div class="col-md-12">
<div class="table-responsive">
<table id="bootstrapdatatable" class="table table-striped table-bordered" width="90%">
<thead>
<th><input type="checkbox" id="checkall" /></th>
<th>ID</th>
<th>Machine Name</th>
<th>Operation Number</th>
<th>File</th>
<th>Delete</th>
</thead>
<tbody>
{% for control in controlmachines %}
<tr>
<td><input type="checkbox" class="checkthis" /></td>
<td>{{ control.id }}</td>
<td>{{ control.machine_name }}</td>
<td>{{ control.operation_no }}</td>
<td>{{ control.control_uploadfile }}</td>
<td><p data-placement="top" data-toggle="tooltip" title="Delete"></span></p></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock content %}
models.py:
class Controlmachine(models.Model):
machine_name = models.CharField(max_length=100)
operation_no = models.IntegerField()
control_uploadfile = models.FileField(upload_to='documents/')
class Meta:
db_table = "controlmachine"
forms.py:
class ControlForm(forms.ModelForm):
class Meta:
model = Controlmachine
fields = ['machine_name', 'operation_no', 'control_uploadfile'] #https://docs.djangoproject.com/en/3.0/ref/forms/widgets/
widgets = { 'machine_name': forms.TextInput(attrs={ 'class': 'form-control' }),
'operation_no': forms.TextInput(attrs={ 'class': 'form-control' }),
'control_uploadfile': forms.ClearableFileInput(attrs={ 'class': 'form-control' }),
}
Do this: Here I have added if condition that is used to connect machine name to uploaded file.
<form action="{% url 'save_machine' %}" method="post">
{% csrf_token %}
<label for="machinename">Select Machine Name:</label>
<select name="machinename" id="machinename">
{% for machine in cmachines %}
<option value="{{ machine.machine_name }}">{{ machine.machine_name }}</option>
{% endfor %}
</select>
<br>
<br>
<label for="operationname">Select Operation Number:</label>
<select id="operationname" name="operationname">
{% for machine in cmachines %}
<option value="{{ machine.operation_no }}">{{ machine.operation_no }}</option>
{% endfor %}
</select>
<br>
<br>
<br>
<input type="submit" value="Save">
</form>
<tr>
{% for choice in choiced_cmachine %}
<td>{{choice.machine_name}}</td>
<td>{{choice.operation_no}}</td>
<td>
{% for file in controlmachines %}
{% if file == choice and file == choice %}
view file
{% endif %}
{% endfor %}
</td>
{% endfor %}
</tr>

How to index formset input fields with list elements

How can I use elements from a list as formset indexes instead of the generic 0,1,2 etc?
Right now I have something like:
Sizes = ["XS", "S", "M","L", "XL"]
SizesFormSet = formset_factory(SizesForm, extra=len(Sizes))
And my formset input fields are indexed as 0,1,2... like so:
<td><input type="number" name="Jaune-0-quantité" id="id_Jaune-0-quantité"></td>
<td><input type="number" name="Jaune-1-quantité" id="id_Jaune-1-quantité"></td>
<td><input type="number" name="Jaune-2-quantité" id="id_Jaune-2-quantité"></td>
...
and I'd like to index them as "XS", "S", "M"
```html
<td><input type="number" name="Jaune-XS-quantité" id="id_Jaune-XS-quantité"></td>
<td><input type="number" name="Jaune-S-quantité" id="id_Jaune-S-quantité"></td>
<td><input type="number" name="Jaune-M-quantité" id="id_Jaune-M-quantité"></td>
The django documentation deals with renaming a formset input field prefix, but it doesn't deal with indexing.
Thanks in advance for the help!
I ended up doing it this way, not using formsets:
#views.py
formsets = []
for couleur in Couleurs:
formset=[]
for taille in Tailles:
formset.append({"name": taille+"-"+couleur, "id": "id_"+taille+"-"+couleur})
formsets.append({"formset":formset, "couleur":couleur})
return render(request, "front/nouvel-article.html", {'form': form, 'formsets': formsets, 'collection': collection, "tailles": [""]+Tailles})
and in my template:
<form action="/nouvel-article/{{ collection }}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Détails</legend>
{{ form|crispy }}
</fieldset>
<fieldset class="form-group">
<legend class="border-bottom mb-4">Quantité</legend>
<table>
<thead>
{% for taille in tailles %}
<th>{{ taille }}</th>
{% endfor %}
</thead>
<tbody>
{% for formset in formsets %}
<tr>
<td>{{formset.couleur}}</td>
{% for field in formset.formset %}
<td><input type="number" name="{{ field.name }}" id="{{ field.id }}"></td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Confirmer</button>
</div>
</form>

how to update django databsae from html?

I want to only update the brand. So I want to see if I can get the post from the input.
print(request.POST.get('brand')) didn't print anything, but I can get print(request.POST.get('url')). Does anyone know why?
Here is my base.html code.
<form action="{% url 'script' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group w-75">
<input type="text" name="url" id="url" class="form-control">
</br>
<button type="submit" class="btn btn-success btn-lg btn-block">submit</button>
</div>
</br>
{% if alldata %}
<table class="table table-striped table-sm" id="">
<thead>
<tr>
<th>Price</th>
<th>Asin</th>
<th>Rank</th>
<th>Brand</th>
<th>CPU</th>
<th>Update</th>
</tr>
</thead>
<tbody>
{% for data in alldata %}
<tr>
<td>{{ data.price }}</td>
<td> {{ data.asin }} </td>
<td>{{ data.rank }}</td>
<td>
<div>
{{ data.brand }} <input type="text" name="brand" id="brand" value="{{data.brand}}">
<button type="submit">Update</button>
</div>
</td>
<td>cpu</td>
<td><button type="submit">Update</button></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</form>
To check All data in request.POST:
print(request.POST)
to print only one 'field'
print(request.POST['field'])

Displaying Unescaped in Django Template

I have a form with a title and body but for certain cases the title should be autofilled to a value from the page:
To solve this I used a hidden input type:
<form action="" method="POST"> {% csrf_token %}
<table>
<tr>
<td>
<b>Title: </b>
</td>
{% url 'forum:new_topic' forum.pk as the_url %}
{% ifequal request.path the_url %}
<td>
{{ modelform.title}}
</td>
{% else %}
<td>
{% autoescape off %}
<input type="hidden" value="{{ modelform.title}}" >
{% endautoescape %}
Re:{{ thread.title }}
</td>
{% endifequal %}
</tr>
<tr>
<td>
<b>Body: </b>
</td>
<td>
{{ modelform.body}}
</td>
</tr>
</table>
<input type="submit" value="Submit" />
</form>
However the way it displays on the page is "> Re: .... and is for some reason not escaping the ending quote and >. I tried single quotes but that prevents submission.
Not sure what direction I should go in.

how to iterate over a list of variable length in django template?

I have a list of values like:
list_of_values = ['clients':['add, view'], 'vendors': ['add', 'delete', 'change'], 'companies': ['add', 'view', 'delete', 'change']]
Using django template tags I have to make a template like:
Activities ADD | VIEW | CHANGE | DELETE
clients checkbox checkbox checkbox checkbox
vendors checkbox checkbox checkbox checkbox
companies checkbox checkbox checkbox checkbox
Kindly let me know how can I achieve this?
List of values looks more like a dictionary to me, assuming it is:
<table>
<tr>
<th>Activities</th>
<th>ADD</th>
<th>VIEW</th>
<th>CHANGE</th>
<th>DELETE</th>
</tr>
{% for key in list_of_values %}
<tr>
<td>{{ key }}</td>
<td>
{% if 'add' in list_of_values.key %}
<input type="checkbox" checked/>
{% else %}
<input type="checkbox"/>
{% endif %}
</td>
<td>
{% if 'view' in list_of_values.key %}
<input type="checkbox" checked/>
{% else %}
<input type="checkbox"/>
{% endif %}
</td>
<td>
{% if 'change' in list_of_values.key %}
<input type="checkbox" checked/>
{% else %}
<input type="checkbox"/>
{% endif %}
</td>
<td>
{% if 'delete' in list_of_values.key %}
<input type="checkbox" checked/>
{% else %}
<input type="checkbox"/>
{% endif %}
</td>
</tr>
{% endfor %}
</table>