I have a tuple which holds multiple color and their codes:
color_list = (
('#CD5C5C', 'Indian Red'),
('#F08080', 'Light Coral'),
('#FA8072', 'Salmon'),
................
)
and this is the model:
class ColorList(models.Model):
color = models.CharField(choices=color_list, max_length=10)
class Product(models.Model):
color_list = models.ManyToManyField(ColorList)
view:
def product_edit(request, pk):
product = get_object_or_404(Product.objects.prefetch_related('color_list'), pk=pk)
context = {'product': product,'color_list': color_list}
return render(request, 'admin/product/product_edit.html', context)
Now I want to edit previously saved data in template using a form:
<div class="form-group">
<label><strong>Color List</strong></label>
<select name="color_list" class="form-control selectpicker" multiple data-live-search="true" >
{% for key, value in color_list %}
{% for pro_color in product.color_list.all %}
<option value="{{ key }}" {% if pro_color.color == key %} selected {% endif %}>
{{ value }}
</option>
{% endfor %}
{% endfor %}
</select>
</div>
I want to show previously selected color with other color options, but using this template code, it generating multiple duplicate <options>. So the problem is how can I use multiple for loop in template with preselected color <options> ?
The reason your colors are duplicating is because you nested two loops unnecessarily to get the key/value pairs. You can use .get_FOO_display() instead.
<div class="form-group">
<label><strong>Color List</strong></label>
<select name="color_list" class="form-control selectpicker" multiple data-live-search="true" >
{% for pro_color in product.color_list.all %}
<option value="{{ pro_color.get_color_display }}" {% if pro_color.color == color_list.color %} selected {% endif %}>
{{ pro_color.color }}
</option>
{% endfor %}
</select>
</div>
https://docs.djangoproject.com/en/dev/ref/models/instances/#django.db.models.Model.get_FOO_display
For Edit Related Issues, Refer Template of Django Admin > Edit User
Probable url will be: http://localhost:8000/admin/auth/user/{id}/change/
Here They Have Permissions column which is Select Many and it ofcause retains its value on refresh too.
Related
I'm manually rendering a modelchoicefield in my form so that I can insert a custom attribute on each option. I'd like to know what template tag I can userto determine if the option is the initial value so that I can set it as the selected option in the dropdown menu on page load.
forms.py
self.fields['formpricing'].choices = ZERO_BLANK_CHOICE + tuple([(t.id, t) for t in FormPricingMethod.objects.filter(industryname=industry)])
self.fields['formpricing'].queryset = FormPricingMethod.objects.filter(industryname=industry)
views.py
formpricing = userprofile.formpricing
form3 = BasisOfPricingForm(request.POST or None, user=user, initial={'formpricing': formpricing})
template
<div class="fieldname">Form Pricing</div>
<div class="fieldvalue">
<select name="formpricing" required="" id="id_formpricing">
{% for value, object in form3.formpricing.field.choices %}
<option typenumber="{{object.typenumber}}" value="{{value}}">
{{object.title}}
</option>
{% endfor %}
</select>
</div>
</div>
Thanks!
Got it.
{% if form3.formpricing.initial.id == value %}selected{% endif %}
I created a model and one of the fields has choices. I created a select form in my template and the choices are not been displayed. I'm not using Forms or ModelForms for a few reasons. But my understanding is that I should be able to make this work using CHOICES in the model, building a form in the template and save the information using the object manager. How can I get the choices to populate the form?
Models.py
class NewRating(models.Model):
EXCELLENT = 'EX'
GOOD = 'GD'
FAIR = 'FR'
BAD = 'BD'
RATING_CHOICES = (
(EXCELLENT, 'Excellent'),
(GOOD, 'Good'),
(FAIR, 'Fair'),
(BAD, 'Bad')
)
function = models.ForeignKey(Function, related_name='frating')
timeline = models.ForeignKey(Timeline, related_name='trating')
rating = models.CharField(max_length=25,choices=RATING_CHOICES)
Views.py
def f_page(request, Function_id):
assignments = Function.objects.get(id=Function_id)
time = Timeline.objects.all()
ratings = NewRating.objects.all()
context = {
'assignments': assignments,
'time' : time,
'ratings' : ratings,
}
return render (request, 'project/pager.html', context)
HTML
<div id=for_rat>
{% for rated in time %}
<form action= "/project/rated" method='POST'>
{% csrf_token %}
{{rated.segment}}
<input type="hidden" name="year" value="{{rated.year}}">
<input type="hidden" name="month" value= "{{assignments.id}}">
<select name="ratings">
<option value="">Choose From List</option>
{% for rating in ratings %}
<option value="{{rating.choices}}">{{rating.choices}}</option>
{% endfor %}
</select>
{% endfor %}
<input type="submit" value="Save">
</form>
</div>
Using {% for rating in ratings %}
{{rating.choices}}
{% endfor %} is not working. Can I set the choices in the models if I'm building my own forms? If yes, what am I doing wrong that this is not rendering?
Easiest, simplest and the 100% working method is:
Get the objects [lets say 'my_Model_with_choices'] with my_Model_with_choices = yourModel.objects.first() and you can get the choices with my_Model_with_choices._meta.get_field('your_foreign_key_variable_name').choices
def f_page(request, Function_id):
assignments = Function.objects.get(id=Function_id)
ratings = NewRating.RATING_CHOICES
context = {
'ratings' : ratings,
}
return render (request, 'project/pager.html', context)
Inside HTML template:
<select class="custom-select col-md-5" name="ratings" id="ratings" required>
<option disabled selected value="">Ethnic Group</option>
{% for value, ratings_group in ratings %}
<option value='{{value}}'>{{ratings_group}}</option>
{% endfor %}
</select>
If you're strictly not willing to use Form or ModelForm, you need to have choices to be iterable which is possible via enum.
You can check my sample code about how to implement choices with enums here.
You'll have to make some tweaks to your context and template after doing this.
You might want to look how to get the list of choices with enum.
try this
{% for rating in ratings %}
<select name="ratings">
<option value="">Choose From List</option>
{% for x, y in rating._meta.get_field('rating').choices %}
<option value="{{ x }}">{% if rating.rating == x %} selected{% endif %}>
{{ y }}
</option>
{% endfor %}
</select>
{% endfor %}
Make sure that this code is outside the
{% for rated in time %}
...
{% endfor %}
block
I want to query data,use the selectfield as a condition,then show the result in a html and use paginage.
my question is when i display my data,the first can display normally but when i click the next_page,the selectfield is none and the data can not display.
what should I do to keep the selectfield when I click the next_page?
Your view should accept an integer to allow for the passing of the current datum. Below is an example:
#app.route('/view/<int:page>',methods=['GET'])
def view(page=1):
if request.method == 'POST':
select = int(request.form.get('select'))
print(select)
per_page = 2
try:
users = User.query.order_by(User.email.asc()).paginate(select,
per_page=per_page,
error_out=False)
except NameError:
users = User.query.order_by(User.email.asc()).paginate(page,
per_page=per_page,
error_out=False)
return render_template('view.html',users=users)
The view would look something like this:
<html>
<head>Welcome</head>
<body>
<form method="POST" action="{{ url_for('view', page=users.prev_num + 1) }}">
<div>
<div>
<span>Please select</span>
<select name="select">
{% for user in users.items %}
<option value="{{ user.id }}">{{ user.username }}</option>
{% endfor %}
</select>
</div>
<button type="submit">Go</button>
</div>
</form>
{% if users.has_prev %}<< Newer users{% else %}<< Newer posts{% endif %} |
{% if users.has_next %}Older users >>{% else %}Older posts >>{% endif %}
</body>
</html>
I have this form:
class UserUsesSourceForm(forms.Form):
# some fields here
username = forms.CharField(label=("Username"), max_length=30, help_text = ("Required"))
provider = forms.ChoiceField(widget=forms.Select(), choices=SOURCES_CHOICES, initial=SOURCES_CHOICES[1])
The available choices are:
E = 'e'
A = 'a'
SOURCES_CHOICES = (
(A, 'A'),
(E, 'E'),
)
The view:
form = UserUsesSourceForm(initial={"username":request.user.username, 'provider':SOURCES_CHOICES[1]})return render_to_response('update_datasource.html', context_instance=RequestContext(request, params))
And the template:
<form action="" method="post">
{% csrf_token %}
{% if form.non_field_errors %}
<p>
{% for error in form.non_field_errors %}
<div class="text-error">{{ error|escape }}</div>
{% endfor %}
</p>
{% endif %}
<div class="control-group">
<label class="control-label" for="id_provider">Data source</label>
<div class="controls">
{{form.provider}}
</div>
</div>
</form>
The problem is that even if the initial value is correctly set, and I can test it in debug (i.e., the form "provider" field initial value is the tuple I want), the final html always show the first element in the select box:
<select name="provider" id="id_provider">
<option value="A">A</option>
<option value="E">E</option>
</select>
..while I'd expect it to have a "default" or "active" option.
Please note that the username field is correctly initialized.
How can I investigate further to find out where the problem is?
You need to pass the option value instead of tuple in initial data:
form = UserUsesSourceForm(
initial={'username':request.user.username,
'provider':SOURCES_CHOICES[1][0]})
I've been doing some custom forms with django but I don't get how to access attributes that a specific form field has attached via the forms.py.
def putErrorInTitle (cls):
init = cls.__init__
def __init__ (self, *args, **kwargs):
init(self, *args, **kwargs)
if self.errors:
for field_error in self.errors:
self.fields[field_error].widget.attrs['title'] = self.errors[field_error][0]
self.fields[field_error].widget.attrs['class'] = "help_text error_field"
cls.__init__ = __init__
return cls
That's how I attached the attibutes to the field.
<dl class="clearfix two">
<dd>
<label for="id_diagnosis">Diagnostico:</label>
<select class="{{form.id_diagnosis.class}}" id="id_equipment_activity-{{ forloop.counter0 }}-id_diagnosis" name="equipment_activity-{{ forloop.counter0 }}-id_diagnosis">
{% for x,y in form.fields.id_diagnosis.choices %}
<option value="{{ x }}" {% ifequal form.id_diagnosis.data|floatformat x|floatformat %}selected="selected"{% endifequal %}>{{ y }}</option>
{% endfor %}
<option value="1000" {% ifequal form.id_diagnosis.data|floatformat '1000'|floatformat %}selected="selected"{% endifequal %}>Otro</option>
</select>
</dd>
<dd class="vertical_center" id="optional_diagnosis"><label for="optional_diagnosis">Diagnostico opcional:</label>{{ form.optional_diagnosis }}</dd>
</dl>
I've been trying to access its attributes:
class="{{form.id_diagnosis.class}}", class="{{form.id_diagnosis.widget.class}}"
And I don't seem to find clear documentation about what's accessible and what's not. Really I would rather have old fashion documentation than django "friendly" one
In other cases it can can be useful to set and get field attributes.
Setting in form's init function:
self.fields['some_field'].widget.attrs['readonly'] = True
... and accessing it in a template:
{{ form.some_field.field.widget.attrs.readonly }}
It looks like you just want to display form errors for each field.
After the form is cleaned or validated in the view, the fields should contain
the error messages. So that you can display them in the template like so:
<form action='.' method='post'>
...
<div class='a-field'>
{{ form.field_1.errors|join:", " }}
{{ form.field_1.label_tag }}
{{ form.field_1 }}
</div>
...
</form>
If however you really want to display the form field attributes then you
can try something like:
{{ form.field_1.field.widget.attrs.maxlength }}
The above answers are correct, however, I'd like to add a note for those who are accessing form fields in a loop.
If you're doing this in a loop like this
{% for field in form %}
{{ field.field.widget.attrs.placeholder }} # field.field is the key here
{% endfor %}