Using Django 3.1 and I'm struggling with a basic tasks.
I've got a form with a field like this:
forms.ModelChoiceField(queryset=StorageSpace.objects.filter(visible=True), widget=forms.RadioSelect)
I would like to do this in my view:
{% for space in form.available_spaces %}
<label class="btn btn-outline-primary">
<input value="{{ space.id }}" data-storage-price={{ space.price }}>{{ space.title }}
</label>
{% endfor %}
But this doesn't work. How can I access the attributes of my objects for each choice?
Can't be that difficult, can it? I really need to set the data attribute, otherwise I would just use{{space}}.
form.available_spaces.field.queryset
lets you access the object behind the choice-field. As simple as that.
Related
I have a Profile Object which has a many to many reationship with a Hobbies object. A profile is used for creating a User. Each User can also have a load of hobbies that are predefined. What I want to do is let Users pick some hobbies they are interested in. However, I am not sure how to display all these Hobbies and let Users pick them on the actual display. Here is the code:
TYPES = (
("Football", "Football"),
("Cricket", "Cricket"),
("Swimming", "Swimming"),
("Cycling", "Cycling")
)
class Hobby(models.Model):
myfield = MultiSelectField(choices = TYPES)
And the User :
class Profile(models.Model):
email = models.CharField(max_length=200)
hobbies = models.ManyToManyField(Hobby)
And the HTML code I use is here:
<span class="fieldname">Hobbies</span>
{% for hobby in all_hobbies %}
<input type="checkbox" name={{hobby}} value={{hobby}}> {{hobby}}<br>
{% endfor %}
However this only displays
What I want it to display is all the hobbies with the choices, instead of the whole Object. I am not sure how to do this and would appreciate any help.
Try doing something like
<span class="fieldname">Hobbies</span>
{% for hobby in all_hobbies %}
<input type="checkbox" name="{{ hobby.myfield }}" value="{{ hobby.myfield }}"> {{ hobby.myfield }}<br />
{% endfor %}
Under Hobby class, you should add the str method that will display the value of your hobby instead of 'Object'
def __str__(self):
return self.myfield
You can also use __unicode__ instead of __str__ if you are with Python 2.x
Edit:
After I read again your question, I understood that your problem was specifically not having several checkboxes for the multiple choices you have, here is how you can show all the choices, you should pass the hobbies field as a context :
{% for value, text in form.hobbies.field.choices %}
<div class="ui slider checkbox">
<input id="id_hobbies_{{ forloop.counter0 }}" name="{{ form.hobbies.name }}" type="checkbox" value="{{ value }}"{% if value in checked_hobbies %} checked="checked"{% endif %}>
<label>{{ text }}</label>
</div>
{% endfor %}
In a Django template, I'm displaying some usernames (or unames) along with check boxes like so:
<form method="POST" action="{% url 'process_unames' %}">
{% csrf_token %}
{% for name in unames %}
<input type="checkbox" name="target{{ forloop.counter0 }}" value="{{ unames|index:forloop.counter0 }}" checked>{{ name }}<br>
{% endfor %}
<button name="duration" value="{{ value }}" type="submit">Submit</button>
</form>
And then in the function process_unames, I'm trying to retrieve all checked unames via:
def process_unames(request, *args, **kwargs):
uname_list = request.POST.getlist('unames')
This is consistently yielding an empty list, regardless of which uname I check or uncheck. How do I fix this? An illustrative example would be great.
In case it matters, I haven't declared any form in forms.py with this Django template. Moreover, note that index is a custom template tag which does the following (and I can vouch it's correctly working):
from django.template.defaulttags import register
#register.filter(name='index')
def index(List, i):
return List[int(i)]
You are checking the wrong variable. You access the input by its name.
So for a single value you would retrieve the data for a form like this
<input type="checkbox" name="user_name" value={{uname}}>
via
request.POST.get('user_name')
See: https://docs.djangoproject.com/en/1.10/topics/forms/#the-work-that-needs-to-be-done
And if you have loop, you still give each relevant input the same name and use request.POST.getlist() to access the values as a list.
See: https://stackoverflow.com/a/23470119/630877
You don't have any fields called "unames" in the template. You have a bunch of unrelated checkboxes called "targetX" where X is a number. Replace that with just name="unames" and your code will work.
Note two things: firstly, you should be using Django's forms framework; and secondly, your filter is pointless because {{ name }} would already by the value in unames, since that is what you are iterating over (and, indeed, you are already using that as the label).
{% for name in unames %}
<input type="checkbox" name="unames" value="{{ name }}" checked>{{ name }}<br>
{% endfor %}
{% for fields in form %}
{{ field.label }}
{{ field }}
{% endfor %}
The {{ field }} will render something similar to:
<input type="text" id="something_id" .../>
Is there a way I can render a field without having to let it wrap it in a tag? So for instance, I render a field and I get (without the input tag):
type='text' id='_something_id'
In this case, I can go ahead to manually add custom classes as and when and where I want like:
<input {{ field }} class='class class-again' required autocomplete='off' />
Is there a way I can do that in Django, render a field without it wrapped in the element?
Obviously, such a hard way of formatting can be tiring if working on tons of fields making such an approach impractical. In my case, I'm just wanting to tailor some css to just two fields, and having to go through Django Forms, or template tags etc, I find the process lengthy
You can do this if you know the input type:
{% for field in form %}
{{ field.label_tag }}
<input type="text" id="{{ field.id_for_label }}" name="{{ field.html_name }}" value="{{ field.value }}"/>
{% endfor %}
If you have different input types you could still go through the fields manually instead of iterating over them (using their name, eg. form.username).
However in most cases it is better to do those things on the backend using the widget API like this:
name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
It is possible. You could write your own HTML code, you know that Django assigns id and name attributes with a format, like: id='something_id'. The name attribute is the important one, you should make sure it is the same that Django would assigns.
Another option is this:
# I will assume you have a field named something
something = forms.CharField(widget=forms.TextInput(attrs={'class':'class class-again''}))
This should do what you need. I hope this helps.
I am using django-transmeta for translation. In the below code, {{ obj.description }} returns the description in the current language of django. What I need is, getting the obj.description_[lang_code]. How can I get it?
{% for lang in languages.all %}
<div id='{{ lang.code }}'>
<input type="text" name="description-{{lang.code}}" value='{{ obj.description }}'/>
</div>
{% endfor %}
As I understood from your comment you want to get description of specific language in for loop?
then simply write a custom filter like in this way
{{ obj|get_lang_info:lang.code }}
here get_lang_info is custom filter.
I want to customize the layout of forms in a formset (that is, I don't want to use .as_table() or .as_p() and the like). I'm trying to get the name of a form field for use in its label's for attribute, but I'm not sure how to go about it. I'm hoping that I won't need to construct a new name/ID for the field from scratch. Here's an example of what I'm working with right now:
{% for form in formset.forms %}
<!-- The field for the "path" form field -->
<label for="{{what do I put here?}}">{{form.fields.path.label}}:</label><input type="text" id="{{django creates this one; do I have to do my own with the for loop counter or something?}}" name="{{probably the same as id}}" />
{% endfor %}
Is there any sort of "create ID for formset field" sort of method?
This is likely what you want.
for="{{ form.your_field.html_name }}"
First, you want to use the form element's id, instead of name.
I tried Django 1.3 Alpha-1 and the following worked:
{% for form in formset.forms %}
<label for="{{ form.my_field.auto_id }}">{{ form.my_field.label }}</label>
{{ form.my_field }}
{% endfor %}
Enjoy!