django form doesn't display labels - django

I'm new in django. I try to create a simple form based on the model.
Imputs are displayed fine but i have problem with the labels.They don't appears on the page.
I can't figure out where is my mistake. For my it should be working fine.
Any idea what's is wrong here?
class RecForm (ModelForm):
class Meta:
model = Rec
fields = ['name', 'kind',]
labels = {
'name': 'Here put your name',
}
home.html
<form action="addrec" method="post">
{% csrf_token %}
{% for i in form %}
{{ i }}
<br><br>
{% endfor %}
<input type="submit" value="Submit">
{% endblock %}

You're rendering the field in your template as {{ i }}, with i being an instance of a BoundField (code). BoundField.__str__ calls widget.render (code) and returns the output. widget.render renders the value of of the widget's template (see widget templates here https://github.com/django/django/tree/4.0.2/django/forms/templates/django/forms/widgets). None of these templates include the label tag.
To render the label tag your should call {{ i.label_tag }} (code), which will render the tag with all attributes Django knows about. Extra attributes may require adjustments.

Related

Not showing the Form in html

This is my model
class showroom(models.Model):
serialno=models.IntegerField(db_index=True,primary_key=True)
carname=models.CharField(max_length=50)
carmodel=models.CharField(max_length=50)
price=models.IntegerField()
rating=models.IntegerField(validators=[MinValueValidator(1),MaxValueValidator(5)])
This is my forms.py
class RegisterForm(ModelForm):
class Meta:
model = showroom
fields =("__all__")
views.py
class carform(CreateView):
model = showroom
form_class=RegisterForm
template_name = "carbrand/carregister.html"
context_object_name='registerform'
html page
{% block content %}
{{registerform}}
{% endblock content %}
It's just showing a blank screen. I have imported all the necessary classes and views. It will make this too long for you so i removed it.can anyone please tell me if anything wrong in my view/form.
The name of the form is not determined by the context_object_name. In fact in a CreateView, the context_object_name does not change anything since no object is passed.
A FormView (and its descendants), always pass the form that is constructed as form to the context. You thus should render this with:
{% block content %}
<form method="post" action="{% url 'some-view-name' %}">
{% csrf_token %}
{{ form }}
<button type="submit">submit</button>
</form>
{% endblock content %}

Django: Accessing queryset in ModelMultipleChoiceField from template

I'm creating a panel where a user can assign an assignment to other users. I'm attempting to build this with the ModelMultipleChoiceField and a form called AssignedUsersForm
forms.py
class AssignedUsersForm(ModelForm):
class Meta:
model = Assignment
fields = ['users']
custom_users = CustomUser.objects.all()
users = forms.ModelMultipleChoiceField(queryset=custom_users, widget=forms.CheckboxSelectMultiple())
template
<form method="post" id="assigned_users_form">
{% csrf_token %}
{{ assigned_users_form.errors }}
{{ assigned_users_form.non_field_errors }}
<div class="fieldWrapper">
{{ assigned_users_form.content.errors }}
{% for user in assigned_users_form.users %}
<div class="myradio">
{{ user }}
</div>
{% endfor %}
<br>
<div style="text-align:center;">
<input class="input-btn" type="submit" value="Save" name='submit_assigned_users_form'>
</div>
</form>
I've successfully rendered each of the options for CheckboxSelectMultiple individually in my HTML.
Unfortunately, each iteration of 'user' renders CustomUser object (#) - the default name for the object.
From what I understand, the Checkbox widget does not pass the original queryset to the template. Thus, I'm unable to access the model attributes of each user and render information such as name, profile picture, etc.
Is there a method of accessing the actual object that's represented in the checklist, instead of the _ str _ value?
I've considered running a parallel iteration of queryset in the template, but I'm not sure if that's possible in Django.
I've also considered creating custom template tags to access each object based on the id in str, but that seems like overkill?
Is there a more intuitive method that I'm missing here?
I found a work around by creating a template_filter that takes the checkbox value and returns the corresponding object to the template.
template_tags.py
#register.filter(name='get_user')
def get_user(user_id):
user = CustomUser.objects.get(pk=user_id.value)
return user
template
<form method="post" id="assigned_users_form">
{% csrf_token %}
{{ assigned_users_form.errors }}
{{ assigned_users_form.non_field_errors }}
<div class="fieldWrapper">
{{ assigned_users_form.content.errors }}
{% for user in assigned_users_form.users %}
<div class="myradio">
{% with customuser=user.data.value|get_user %}
{{user.tag}} {{customuser.first_name }}
{% endwith %}
</div>
{% endfor %}
<br>
<div style="text-align:center;">
<input class="input-btn" type="submit" value="Save" name='submit_assigned_users_form'>
</div>
</form>
Essentially, this code looks at the checkbox widget iteration (user) and gets the value, passes that value to the template tag and then returns the associated object back to the page.
Not the best solution given that you're repeating the query search for each object, rather than gathering them all in one go. But this is the best I could come up with.

django-taggit add tags form field in DetailView

I'd like to add a single form input field to a DetailView that will append tags to my model. I'm not sure if I need a separate view for that, or I can simply add a form. Using django-bootstrap3, I have the following:
<div class="row">
<form action="add-tag" method="post"
enctype=multipart/form-data>
{% csrf_token %}
{{ form.media }}
{% bootstrap_field form.tags show_label=False %}
<input type="submit" value="{% trans "submit" %}"/>
</form>
</div>
forms.py:
class MyModelAddTagsForm(forms.ModelForm):
class Meta:
model = models.MyModel
fields = ('tags',)
I get the error:
BootstrapError at /someurl/1/view
Parameter "field" should contain a valid Django BoundField.
I'm not sure what else I exactly need. A view and url or modifying my DetailView? Or using an UpdateView instead?

Model Formset - By Default model formset is rendering one extra field (2 fields in total)

My model formset without even defining "extra" parameters in modelformset_factory is rendering one extra field in the template. I have tried many variations but it didn't work. If I print the form (the model form) on the command line it just prints a single form field as required but on model formset it prints 2 by default.
Here is my code.
models.py
class Direction(models.Model):
text = models.TextField(blank=True, verbose_name='Direction|text')
forms.py
class DirectionForm(forms.ModelForm):
class Meta:
model = Direction
fields = ['text',]
views.py
def myview(request):
Dirset = modelformset_factory(Direction, form=DirectionForm)
if request.method == "POST":
dir_formset = Dirset(request.POST or None)
if dir_formset.is_valid():
for direction in dir_formset:
text = direction.cleaned_data.get('text')
Direction.objects.create(text=text)
return render(request, "test/test.html", {'DirFormSet':Dirset})
template
{% block content %}
<form method="POST">{% csrf_token %}
<div id="forms">
{{DirFormSet.management_form}}
{% for form in DirFormSet %}
{{form.text}}
{% if error in form.text.errors %}
{{error|escape}
{% endif %}
{% endfor %}
</div>
<button id="add-another">add another</button>
<input type="submit" />
</form>
{% endblock %}
As a side note, if I submit data on this form it gives the following error.
Error
Exception Type: MultiValueDictKeyError
Exception Value:"u'form-0-id'"
By default, modelformset_factory creates one extra form. If you don't want any extra forms, set extra=0.
Dirset = modelformset_factory(Direction, form=DirectionForm, extra=0)
The KeyError is because you have not included the form's id field in your template. You should have something like:
{% for form in dir_formset %}
{{ form.id }}
{{ form.text }}
...
{% endfor %}
Note that you should be passing the formset instance dir_formset when rendering the template, not the class DirFormSet. Your view should be something like
return render(request, "test/test.html", {'dir_formset': dir_formset})
then the template should be updated to use dir_formset instead of DirFormSet.

Django sub-Form not display label when rendered on template

After reading over the Docs, and working with Django forms for quite a while, it would seem pretty standard to me that {{ form.as_p }} in the template would render a Django form. However, my situation is a bit different.
I have 2 checkboxes in my form:
class FORM(forms.Form):
field_a = forms.BooleanField(initial=False, label =('FIELD-A'))
field_b= forms.BooleanField(initial=True, label=('FIELD-B'))
I pass the form object as most would from the view:
context = {
'FORM':FORM(),
}
return render_to_string(template, context)
I am trying to use basic 'if' logic to see if I should display one, or both of the fields. I know most would say 'Just name them two separate forms', but I would prefer to keep them as one form for organization purposes.
THE PROBLEM
{% if BoolValue' %}
<form action='' method='post'>
{{ FORM.field_a }}
</form>
{% endif %}
This returns only the field, and not the field label (so just a checkbox). Going off of the Docs and other StackOverflow Questions, this should display the entire form, including the label, yet it doesn't.
These methods still work, however:
METHOD 1
{% for field in FORM%}
<div class="form">
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
This will display both forms, with their respective labels, and field inputs (checkboxes)
METHOD 2
{{ FORM.as_p }}
The traditional way of rendering the entire form will display both fields and labels, it is virtually identical to Method 1 in style and formatting.
EDIT
METHOD 3
{{ FORM.field_a.label_tag }} {{ Form.field_a }}
This will display the label and the form field. A possible work around, but I am looking for why {{ Form.field_a }} does not work on its own
So...
Why can I not render that individual form with its respective label? I am not looking for a work around so to speak, as I would like both fields to be under that one form. Any ideas?
Have you tried {{ FORM.field_a }} {{FORM.field_a.label_tag}}?