2👍
You need to override the clean method of your admin form:
def clean(self):
super(CustomItemForm, self).clean() #if necessary
if 'region' in self._errors:
"""
reset the value (something like this i
think to set the value b/c it doesnt get set
b/c the field fails validation initially)
"""
region = Region.objects.get(pk=self.data['region'])
self.initial['region'] = region.id
self.cleaned_data['region'] = region
self.region = region
# remove the error
del self._errors['region']
return self.cleaned_data
1👍
If you’re having trouble having django accept the value you selected, because it doesn’t think it should have been there in the first place, have the queryset refer to every possible value, but then override the “choices” attribute with an empty set. The latter part will avoid django construct a huge option list that is just going to be overridden by the dynamic javascript.
I know this isn’t drop-in-able for the admin screens, but I found this page while looking to do a similar thing for non-admin, so I thought I’d answer it here, too. Here’s what I’m using:
in views.py:
from django.shortcuts import render_to_response
from django import forms
from django.template import RequestContext
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.core import serializers
# other imports
class AddRouteForm ( forms.Form ):
router = forms.ModelChoiceField ( queryset=Router.objects.all() )
peer = forms.ModelChoiceField ( queryset=Peer.objects.all() )
peer.choices = []
# other stuff not relevant
def get_peers ( request ):
router_id = request.GET['router_id']
router = Router.objects.get(id=router_id)
data = serializers.serialize ( "json", router.peer_set.filter(transit_capable=True) )
return HttpResponse ( data, content_type="text/json" )
def add_route ( request ):
if request.method == "POST":
form = AddRouteForm ( request.POST )
if form.is_valid ():
# TODO something here
return HttpResponseRedirect ( reverse ( "staticroute.views.index" ) )
else:
form = AddRouteForm ()
return render_to_response ( "staticroute/add_route.html", locals(), RequestContext(request) )
In the html file (jQuery needs to be loaded too):
<form method="POST">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Add Route" />
</form>
<script>
$("#id_router").change ( function () {
var router_id = $('#id_router').val();
var items = [];
items.push ( '<option value="" selected="selected">---------</option>' );
$("#id_peer").html ( items.join('') );
if ( router_id != "" ) {
$.getJSON ( '{% url staticroute.views.get_peers %}', {router_id:router_id}, function(data) {
$.each ( data, function ( index, val ) {
items.push ( '<option value="' + val.pk + '">' + val.fields.description + ' (' + val.fields.address + ')</option>');
} );
$("#id_peer").html ( items.join('') );
} );
}
} ).change();
</script>
0👍
I solved that problem not with proposed libraries (with simple javascript), but exist another problem: when i changed country – select region changes automatically, but i can’t save new region value (when another region from the same country – not problem), because error Select a valid choice. That choice is not one of the available choices.
Models are the same in first question, but default value for model country equal 1.
My first way was change country select through formfield_key function,
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'region':
kwargs["queryset"] = Region.objects.filter(country=self.country)
return db_field.formfield(**kwargs)
but i don’t know is the saving objects, or editing objects.
Here wrote – the best way is changing through form
and now i have code:
class Item(models.Model):
country = models.ForeignKey(Country, default=1)
region = models.ForeignKey(Region, related_name='')
class ItemAdmin(admin.ModelAdmin):
form = CustomItemForm
prepopulated_fields = {"alias": ("name",)}
list_filter = ('country', 'category',)
class CustomItemForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
try:
country = kwargs['instance'].country
except KeyError:
country = 1
super(CustomItemForm, self).__init__(*args, **kwargs)
self.fields['region'].queryset = Region.objects.filter(country=country)
- [Django]-Django QuerySet querying or filtering "Odd" and/or "Even" value in a particular field
- [Django]-Dealing with foreign characters in django query
- [Django]-Django Model validate_unique method don't raise ValidationError
- [Django]-Error connecting Django 2.0 with sql server 2014 using python 3.6
- [Django]-May not set both `read_only` and `write_only`