Django选项字段与类别

时间:2012-01-23 02:32:57

标签: javascript python django django-models django-forms

我的models.py中有以下代码(删除了不相关的字段):

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)

和我的utils.py(原文来自django-profiles,即解析表单):

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

现在,我想做的是拥有一个表格选项,其中包含我已经拥有的namechoice_type列。问题是我真的不知道如何将一个选项绑定到一个类别,并让用户在创建他们的个人资料时,根据choice_type中的选择选择编程语言或框架

我认为它涉及一些JS,但这并不像django代码那么多问题。

1 个答案:

答案 0 :(得分:6)

你想要制作这些实际的模型,所以你会有这样的东西:

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)

从可维护性的角度来看,这不仅更好(编程语言确实会发生变化:新版本会出现问题,旧版本会消失),但它也会为您提供更大的查询灵活性。

然后,您只需在ModelForm字段中为类别添加字段:

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

而且,在您的表单中,您最终会得到一个包含完整类别列表的选择,另一个包含完整语言列表。然后,您只需要一些AJAX来为您进行过滤:

<强> views.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('<option value="'+item.id+'">'+item.name+'</option>');
                });
                $('#id_planguage').html(output.join(''));
            });
        }
    }
    updateLanguageChoices();
    $category.change(updateLanguageChoices);
});