Crispy form: render a field as HTML - django

I've a form that contains various fields, some of them should be read-only, but instead of using a "read-only" field i would like to rednder them as HTML.
For examples i want:
<p>{{form.text.value}}</p> to be used. so that it's rendered as pure html and not as an input.
there's the HTML tag that works as a template, but I can't figure out how (and if) i can use it.
Assuming that my field is called text, what should I use to render it?
HTML("This is the text {{text}}") this does not work :(
Or should I create a new template for a new Field in oreder to render it as I want?

I didn't use crispy form before but I try to help you. In a regular form, You can use disabled=True in your related form field. It automatically adds read-only feature to the template and an additional validation to avoid from changing the field.
According to docs:
The disabled boolean argument, when set to True, disables a form field using the disabled HTML attribute so that it won’t be editable by users. Even if a user tampers with the field’s value submitted to the server, it will be ignored in favor of the value from the form’s initial data.
So it will be much safer for your form.
An example:
class ExampleForm(forms.Form):
readonly_field = forms.CharField(disabled = True)
Then in your HTML template:
<form method = "POST">
{% csrf_token %}
{{ form }}
<input type = "submit" value = "Submit">
</form>
I guess you can handle with adding extra crispy-form template tags.

Related

Force Django to recognize a model field value as a template tag value?

I am allowing users to create custom templates, and when doing so they are building off of my own base template with context variables.
So my own template that is used as a base will have a line such as..
<h3>1.0: Contract Specifics for {{ first_name }}</h3>
Now when the user edits this form I am escaping the curly brackets so they store as actual curly brackets in the form field when the user saves their custom template.
Now a user will click save and in the model field there will be raw HTML stored as a TextField and is stored in the database as such...
Now I need to render this in my django template later on but, I need {{ first_name }} to be replaced the actual context variable. unfortunately in my django template when I render this specific form field to display the HTML
{% autoescape off %}
{{ contract_detail }}
{% endautoescape %}
it displays as..
1.0: Contract specifics for {{first_name}}
Is there anyway to force django to recognize this as a template variable and render this correctly, maybe I need some sort of custom functionality, or templatetag?

Django Updateview not saving when in html but saves in admin

I have a big form, some fields, depends on other fields value to compute.
Since so, i used jquery blur to submit the form each time user done editing a field and redirect it to updateview again with new values.
I have this day_absent and amount absent to test this.
If i just put form.day_absent in the form and put object.amt_absent, it doesnt save the form. But if i put form.amt_absent, it saves the form.
Why is that? I do not wish to put amt_absent as editable, it should just be the day_absent.
class PayrollTransactionUpdate(LoginRequiredMixin,UpdateView):
model = t_pay
template_name = 'payroll/transaction/update.html'
fields = [
'day_absent',
'amt_absent',
]
<div id='input-item' class="col-1">
{{ form.day_absent }}
{{ form.day_absent.errors}}
</div>
<div id='item' class="col-2">
{{ object.amt_absent }}
</div>
Couple of points:
When you use {{object.amt_absent}}, you are not rendering the form for the field amt_absent, rather just the value saved in the DB.
You added amt_absent as a field to be included in the UpdateView, so, until and unless this field is not required, the form will keep throwing error for this field. That is why your form works when you include both the fields. You can check all errors by using {{form.errors}} or field specified errors by using {{form.amt_absent.errors}} in your template.

how to differentiate between already created and new objects in the template while using model formset

I am not quite sure about if i am taking the right approach to accomplish this. What i want is to (change the css for) / (use some jQuery methods on) the form elements rendered by the modelformset that have pre-filled data. For example i have the following modelformset.
EduFormSet = modelformset_factory(models.CandidateDegree,
form=forms.CandidateDegreeForm)
edu_formset = EduFormSet(prefix='candidate_degree',
queryset=models.CandidateDegree.objects\
.filter(candidate=can))
when i pass this formset to the template it renders forms for all the existing CandidateDegree objects with the pre-filled data and a blank form as well.
What i am trying to achieve is not to show the pre-filled forms but just the data for the objects that are already created and append an edit button to the element (using jQuery) which would then show the form. And at the end of the object list show the blank form generated by formset.
i am aware that i could pass all the CandidateDegree objects related to a Candidate as a seperate dictionary to show the information. but in that case how do i append the form to the formset so that the dynamically generated forms become the part of the formset and all the information is saved when a user clicks on a submit button.
what would be the best approach to achieve something like this ?
You don't have to show the complete form, you can loop over the formset like this:
{% for form in edu_formset %}
form.FIELDNAME#1.value
form.FIELDNAME#2.value
etc.
{% endfor %}
<!-- Manually render empty form for new entry -->
<div class='input'>
<label>Locality: </label> <input id="FIELDNAME#1" disabled=disabled value="">
<label>Country: </label> <input id="FIELDNAME#2" disabled=disabled value="">
etc.
</div>
So you're only showing the database values of all objects send to the template, not the form inputs.
Then indeed with minimal jquery (or plain javascript) you can show/hide the div.input

How to pass a value to Django-Modelform in InputHidden IntegerField without even disturbing visible field in template

I created a Django model with three fields in which one of them is hidden and rest of them are visible
1.CharField
2.IntegerField (Hidden Field)
3.DateTimeField
I made this hidden by using following code :
class HostCreateForm(forms.ModelForm):
class Meta:
model = Host
widgets = {
'Zone_Vale': forms.HiddenInput()
}
To view this form, i am using following code in my temlate:
<form action="" method="POST">
{{ form.as_p }}
<input type="submit" value="{% trans "Add host" %}" />
Everything is fine but i want to pass a variable in this input hidden layer also. I a not getting any idea to do this. I tried to do by customizing the template (refer this link:) https://docs.djangoproject.com/en/dev/topics/forms/ `
For example {{ form.as_p}} will return a form containing two visible field and the data into them is :(what user had entered it) and a hidden field. So, I want to pass a variable to that hidden field from template.html file
It doesn't work also. Need your help
If you feel like being dirty, a fast solution is to populate this field using javascript. The right way should be using the "initial" parameter when instantiating the form object at view.py
Reference: https://docs.djangoproject.com/en/1.3/ref/forms/api/#django.forms.Form.initial
Even being very dirty, some javascript solution like this shoud work too:
(using jQuery. Adapt for your needs)
<script type="text/javascript">
$(document).ready(function(){
$('form input[name$="Zone_Vale"]').val(DESIRED_HIDDEN_VALUE)
})
</script>
But don't be proud of being doing that.
You won't be able to pass a variable to the field at the template level, given how you're rendering the template.
If you really, absolutely must pass a variable to the form at the template level, I would suggest creating a template tag that will:
Resolve your variable from the request context
Instantiate the form class using the variable as part of the initial data for the form
Add the form to the context to be rendered

Django access field's value dynamically by keyword argument to pass to template

I want to create an edit form for a single field in my model, where the textarea is prefilled with the current value for that field. However, the exact field name is not hardwired, and I want it to be specified by the url.
My model is called Topic. Two example fields are Notes and Objectives. I can hardwire the field value as in the following:
urls.py
(r'^/(?P<topicshortname>\d+)/(?P<whichcolumn>[^/]+)/edit/$', 'mysyte.myapp.views.edit_topic_text'),
views.py
def edit_topic_text(topicshortname, whichcolumn):
thetopic = Topic.objects.get(topic__shortname__iexact = topicshortname)
content = Topic.objects.get(topic__shortname__iexact = topicshortname).objective
return render_to_response('topic_text_edit.html', locals())
topic_text_edit.html
<form method="post" action="../save/">
<textarea name="content" rows="20" cols="60">{{ content }}</textarea>
<br>
<input type="submit" value="Save"/>
</form>
I can also do the hardwiring in the template by using {{ thetopic.objective }}, but if I visited http://mysite.com/topic/Notes/edit/ both of these would prepopulate the form with the objective value, not the notes value.
Can I use the 'whichcolumn' url argument to specify which field to update in the object?
You can use getattr to get the value of an attribute by name. For your example:
def edit_topic_text(topicshortname, whichcolumn):
thetopic = Topic.objects.get(topic__shortname__iexact = topicshortname)
content = getattr(thetopic, whichcolumn)
return render_to_response('topic_text_edit.html', locals())
However, you should be also aware of the security implications of this. Users will be able to edit any field on the model they like by changing the url.
You should either check the value of whichcolumn before doing anything else with that data, or limit the possibilities in the urlconf with a more specific regular expression, eg:
(r'^/(?P<topicshortname>\d+)/(?P<whichcolumn>(Notes|Objectives))/edit/$', 'mysyte.myapp.views.edit_topic_text'),
You also mentioned fields 'Notes' and 'Objectives' but are accessing the field 'objective', so you may need to map the values of whichcolumn to the field name you are interested in, eg:
(r'^/(?P<topicshortname>\d+)/Objectives/edit/$', 'mysyte.myapp.views.edit_topic_text', {'whichcolumn': 'objective'}),
(r'^/(?P<topicshortname>\d+)/Notes/edit/$', 'mysyte.myapp.views.edit_topic_text', {'whichcolumn': 'note'}),
Another thing you should be aware of is that you where accessing the database twice by calling Topic.objects.get(...) twice. You should reuse the value of thetopic.
you should separate the two concepts of Notes and Objectives in two different classes, then use them in your Topic main class as reference
it would be easier for you to retrieve your object type and populate the correct one