Campo de opciones de Django con categorías.

Tengo el siguiente código en mi models.py (eliminé campos irrelevantes):

class Choices(models.Model): name = models.CharField(max_length=300) choice_type = models.CharField(max_length=200) def __unicode__(self): return self.name class UserProfile(models.Model): user = models.ForeignKey(User, unique=True) planguages = models.ManyToManyField(Choices) 

y mi utils.py (originalmente de los perfiles django, que son formas de análisis):

 def get_profile_form(): profile_mod = get_profile_model() class _ProfileForm(forms.ModelForm): planguages = forms.ModelMultipleChoiceField(queryset=Choices.objects.all(), required=False, widget=forms.CheckboxSelectMultiple) class Meta: model = profile_mod exclude = ('user',) # User will be filled in by the view. return _ProfileForm 

Ahora, lo que me gustaría hacer es tener una tabla Opciones, que tendrá las columnas name y choice_type , que ya tengo. El problema es que realmente no sé cómo puedo vincular una opción a una categoría y hacer que un usuario, cuando esté creando su perfil, elija un lenguaje de progtwigción o un marco, según la elección en choice_type .

Supongo que implicaría algo de JS, pero eso no es tanto problema como el código django.

Vas a querer hacer estos modelos reales, por lo que tendrías algo como esto:

 class ProgrammingCategory(models.Model): name = models.CharField(max_length=200) class ProgrammingLanguage(models.Model): category = models.ForeignKey(ProgrammingCategory, related_name='languages') name = models.CharField(max_length=300) class UserProfile(models.Model): user = models.ForeignKey(User, unique=True) planguages = models.ManyToManyField(ProgrammingLanguage) 

Esto no solo es mejor desde el punto de vista de la capacidad de mantenimiento (los lenguajes de progtwigción cambian: surgen otros nuevos, los viejos se extinguen), sino que también le brinda mucha más flexibilidad para realizar consultas.

Luego, simplemente agregue un campo a su ModelForm para las categorías:

 class UserProfileForm(forms.ModelForm): ... category = forms.ModelChoiceField(queryset=ProgrammingCategory.objects.all(), required=False) 

Y, en su formulario, terminará con una selección con una lista completa de categorías y otra con una lista completa de idiomas. Entonces, todo lo que necesita es algo de AJAX para hacer el filtrado por usted:

vistas.py

 from django.core import serializers from django.http import HttpResponse, HttpResponseBadRequest def ajax_get_languages_for_category(request): cat_id = request.GET.get('cat_id') if cat_id is not None: category = get_object_or_404(ProgrammingCategory, id=cat_id) data = serializers.serialize('json', category.languages.all()) return HttpResponse(data, mimetype='application/json') else: return HttpResponseBadRequest() 

script.js

 $(document).ready(function(){ var $category = $('#id_category'); function updateLanguageChoices() { var selected = $category.val(); if (selected) { $.getJSON('/path/to/ajax/view/', { cat_id: selected }, function (data, jqXHR) { var output = []; $.each(data, function(i, item){ output.append(''); }); $('#id_planguage').html(output.join('')); }); } } updateLanguageChoices(); $category.change(updateLanguageChoices); });