I have the following models:
class Category(models.Model):
name = models.CharField(max_length=40)
class Item(models.Model):
name = models.CharField(max_length=40)
category = models.ForeignKey(Category)
class Demo(models.Model):
name = models.CharField(max_length=40)
category = models.ForeignKey(Category)
item = models.ForeignKey(Item)
In the admin interface when creating a new Demo, after user picks category from the dropdown, I would like to limit the number of choices in the "items" drop-down. If user selects another category then the item choices should update accordingly. I would like to limit item choices right on the client, before it even hits the form validation on the server. This is for usability, because the list of items could be 1000+ being able to narrow it down by category would help to make it more manageable.
Is there a "django-way" of doing it or is custom JavaScript the only option here?
MultipleChoiceField in Django Forms is a Choice field, for input of multiple pairs of values from a field. The default widget for this input is SelectMultiple. It normalizes to a Python list of strings which you one can use for multiple purposes.
You would have to add blank=True as well in field definition. If the model field has blank=True, then required is set to False on the form field. Otherwise, required=True. Don't forget to reset and sync DB again after changing this.
editable=False will make the field disappear from all forms including admin and ModelForm i.e., it can not be edited using any form. The field will not be displayed in the admin or any other ModelForm.
The simplest way is by using the field option blank=True (docs.djangoproject.com/en/dev/ref/models/fields/#blank).
Here is some javascript (JQuery based) to change the item option values when category changes:
<script charset="utf-8" type="text/javascript">
$(function(){
$("select#id_category").change(function(){
$.getJSON("/items/",{id: $(this).val(), view: 'json'}, function(j) {
var options = '<option value="">-------- </option>';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';
}
$("#id_item").html(options);
$("#id_item option:first").attr('selected', 'selected');
})
$("#id_category").attr('selected', 'selected');
})
})
</script>
You need a view to be called on the /items/ URL that supplies a JSON list of the valid items.
You can hook this into your admin by using model admin media definitions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With