How to edit html content in Django forms? - html

Because I am not from English Naive country.
Default html content from Django form, is not suitable for my country.
Could someone tell me how to edit html content in forms.py?
I just want to keep English variable for later SQL column settings, but change html content in form.
in forms.py
class DjUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = DjUser
fields = ('username', 'email', 'password')
in html
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ user_form.as_p }}
<input type="submit" value="註冊">
</form>
It showed all English content in html, like Username, Email Address etc..
The thing I needed is 使用者名稱, 電子信箱 etc.. The html contents I want to edit:

You can use attr for styling and naming you're form fields, it will go something like this:
class DjUserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={
'class': 'my-class',
'placeholder': '使用者名稱, 電子信箱',
}))
also you will perhaps need to do some localization for you're application.

Related

Add styling to form.as_div in Django

I am rendering a model form in Django using {{ form.as_div }}
It is rendering as expected as I want each field wrapped in a div.
I would now like to add a class to this auto generated div.
adding widgets in the forms.py file only adds attribute to the input field itself and not the div around the field.
Can someone point me in the right direction to add attributes to the div instead of the input field?
{{ form.as_div }} is not possible in Django but, you can do like this
====== in views.py =========
def DemoView(request):
form = StudentForm()
context = {'form':form}
return render(request,'demo.html',context)
======= in html file ========
<h1>Student Form</h1>
<form action="" method="get" >
{% for fm in form %}
<div>
<label>{{fm.label}}</label>
<p>{{fm}} </p>
</div>
{% endfor %}
</form>
======= Output =========
since django 4.1 you can use "as_div"!
I myself need this possibility in an earlier Version so i built myself an abstract Formclass containing my version of "as_div" derived from the existing render-functions:
class DivRenderer():
"""
as_div: abstract class
"""
def as_div(self):
"Return this form rendered as HTML <divs>s - according to client-Layout."
return self._html_output(
normal_row='<div class="form-group input" %(html_class_attr)s> %(errors)s%(field)s%(help_text)s %(label)s</div>',
error_row='<div%s</div>',
row_ender='</div>',
help_text_html='<br><span class="helptext">%s</span>',
errors_on_separate_row=False,
)
pass
and than using it simply while defining my forms like:
class someThingForm(forms.ModelForm, DivRenderer):
readonly = …
…
and than just using {{ form.as_div }} in the Templates
However!: The as_div-function is different as the one from 4.1 - so be careful not to expect the same behaviour!
hope it helps
Karl

How do I access a single field while using For Loop to iterate through all the fields of a ModelForm in Django Template?

I have a model which has four ForeignKey fields, so they are dropdown fields in the form.
class Package(models.Model):
patient=models.ForeignKey(Patient, on_delete=CASCADE)
diagnosis=models.ForeignKey(Diagnosis, on_delete=CASCADE)
treatment=models.ForeignKey(Treatment, on_delete=CASCADE)
patient_type=models.ForeignKey(PatientType, on_delete=CASCADE)
date_of_admission=models.DateField(default=None)
max_fractions=models.IntegerField(default=None)
total_package=models.DecimalField(max_digits=10, decimal_places=2)
The forms.py:
class PackageForm(ModelForm):
class Meta:
model=Package
fields='__all__'
widgets={
"patient_type" : forms.Select(attrs={"onblur":"mf();"}),
"max_fractions" : forms.NumberInput(attrs={"onfocus":"mf();", "onblur":"tp();"}),
"total_package" : forms.NumberInput(attrs={"onfocus":"tp();", "onblur":"onLoad();"}),
'date_of_admission': DateInput(attrs={'type': 'date'}),
The views.py:
def package_view(request):
if request.method=='POST':
fm_package=PackageForm(request.POST, prefix='package_form')
if fm_package.is_valid():
package=fm_package.save()
IpdReport.objects.create(patient=package.patient, package=package)
fm_package=PackageForm(prefix='package_form')
return render (request, 'account/package.html', {'form5':fm_package})
else:
fm_package=PackageForm(prefix='package_form')
return render (request, 'account/package.html', {'form5':fm_package})
The Template:
<form action="" method="post" novalidate>
{% csrf_token %}
{{form5.non_field_errors}}
{% for fm in form5 %}
<div>
{{fm.label_tag}}
{{fm}}
<span>{{fm.errors|striptags}}</span><br><br>
</div>
{% endfor %}
<button type="submit" id="savebtn">Save</button>
</form>
Now, what I want is to insert an Anchor Tag next to all the foreign_key fields, in the template, to add a new object into the original table. For example, an Add Patient option next to the Patient's dropdown field, when clicked, a new, small window would show up with Patient form. The user enters the new patient's data, saves it and the same name shows up in the dropdown.
But as I am using a For Loop in the template, how would I be able to access those foreign key fields and apply the options? Any suggestions, please?
If it isn't a problem I would move away from rendering all of the fields with the 'forloop'. Instead I would use notation: form.field to render different fields. So it would look like:
{{ form.patient.label_tag }}
{{ form.patient }}
It should be much easier to navigate through fields this way, but of course it will require more typing :)

TextAreaField renders with itself (HTML code in readable text format) as its prepopulated text value

I'm rendering a WTForms TextAreaFields with Jinja2 in a Flask application and it has it's own HTML code as its prepopulated text value, although the default property (which should specify the prepopulated value) is set to empty string ''.
Form definition:
channels = TextAreaField('channels', default='')
Jinja2 template HTML file:
{% for c in e.form.conditions %}
{{ c.form.channels }}
{% endfor %}
Result (rendered, visible to end-user, should be empty string ''):
<textarea id="channels" name="channels"></textarea>
... (other iterations)
Result (HTML):
<textarea class="form-control" id="conditions-0-channels" name="conditions-0-channels"><textarea id="channels" name="channels"></textarea></textarea>
... (other iterations)
I double-checked using the Pycharm debugger and the TextAreaField as a whole object shows as the HTML result above, even though none of its properties contain the visible result string (also above), and the default property is equal to '' even though the result doesn't show so.
Bonus hint: for some reason, if the form containing the channels field is not part of a FormField inside a WTForms FieldList, this problem does not occur.
I don't know what on earth is going wrong with this combination of FieldList, FormField and TextAreaField, but if you call {{ c.form.channels.data }} (with extra .data) in your Jinja2 template HTML file instead of {{ c.form.channels }} then everything works fine.
Wow THANK YOU! I'm not sure what's going on either but this solved the issue for me too. I had some similar findings shown below:
Forms.py
class ChannelForm(FlaskForm):
notes = TextAreaField('Notes', render_kw={'class': 'form-control'}, default="")
channels.html
# These:
{{ channels.notes.data }} # Working solution
{{ channels.notes(value="test Value") }}
# Render these:
<textarea class="form-control" id="notes" name="notes"></textarea>
<textarea class="form-control" id="channels-0-notes" name="channels-0-notes" value="Test Value"><textarea class="form-control" id="notes" name="notes">
Test</textarea>

django form to apply for designed html elements

I hve this html file:
<form method='POST'>
{% csrf_token %}
<input name='foo'/>
<button type="submit">submit</button>
</form>
Now, imagine this form has css atributes behind, I just want a form which would configure some inputs. For an example. The field is required, the min length is 10 chars, etc etc.
How could i approach that with Django forms?
is the something like:
from django import forms
class inputform(forms.Form):
input_line = forms.CharField(max_length=20, min_length=10, name='foo')
how would i apply that to vies.py and how to get errors out to html?
Would appreciate your reply.
you can try this.
class inputForm(forms.Form):
input_line = forms.CharField(max_length=30, widget=forms.TextInput(attrs={'class' : 'input-field form-control'}))
def clean(self, *args, **kwargs):
cleaned_data = super(inputForm, self).clean()
my_input = self.cleaned_data.get("input_line")
if not my_input:
raise forms.ValidationError('This field is required')
if len(my_input) < 10:
raise forms.ValidationError('the min length is 10 character')
return cleaned_data
the clean() method is used for validating input from form.

Django 'ManagementForm data is missing or has been tampered with' when saving modelForms with foreign key link

I am rather new to Django so this may be an easy question. I have 2 modelForms where there is a ForeignKey to another. My main goal is to save Indicators with a link to Disease (FK), such that for a particular disease, you can have multiple indicators.
With the code below, I get an error when I hit submit that says 'ManagementForm data is missing or has been tampered with'. Also, the code in views.py does not seem to be validating at the 3rd 'if' statement where there is a return HttpResponseRedirect. However, when I check my database, the values from the form have been written. Any ideas on why the error has been raised? and how to fix it?
My code is below:
models.py
#Table for Disease
class Disease(models.Model):
disease = models.CharField(max_length=300)
#Tables for Indicators
class Indicator(models.Model):
relevantdisease = models.ForeignKey(Disease)
indicator = models.CharField(max_length=300)
forms.py
class DiseaseForm(forms.ModelForm):
class Meta:
model = Disease
class IndicatorForm(forms.ModelForm):
class Meta:
model = Indicator
DiseaseFormSet = inlineformset_factory(Disease,
Indicator,
can_delete=False,
form=DiseaseForm)
views.py
def drui(request):
if request.method == "POST":
indicatorForm = IndicatorForm(request.POST)
if indicatorForm.is_valid():
new_indicator = indicatorForm.save()
diseaseInlineFormSet = DiseaseFormSet(request.POST, request.FILES, instance=new_indicator)
if diseaseInlineFormSet.is_valid():
diseaseInlineFormset.save()
return HttpResponseRedirect('some_url.html')
else:
indicatorForm = IndicatorForm()
diseaseInlineFormSet = DiseaseFormSet()
return render_to_response("drui.html", {'indicatorForm': indicatorForm, 'diseaseInlineFormSet': diseaseInlineFormSet},context_instance=RequestContext(request))
template.html
<form class="disease_form" action="{% url drui %}" method="post">{% csrf_token %}
{{ indicatorForm.as_table }}
<input type="submit" name="submit" value="Submit" class="button">
</form>
You have neither diseaseFormSet nor diseaseFormSet's management form in your template, yet you try to instantiate the formset. Formsets require the hidden management form which tells django how many forms are in the set.
Insert this into your HTML
{{ diseaseFormSet.as_table }}
{{ diseaseFormSet.management_form }}