Django选项字段与类别

Mil*_*los 1 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)
Run Code Online (Sandbox Code Playgroud)

和我的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
Run Code Online (Sandbox Code Playgroud)

现在,我想要做的是有一个表选择,它将包含我已经拥有的列namechoice_type列.问题是我真的不知道如何将一个选项绑定到一个类别,并让用户在创建他们的配置文件时,根据选择选择一种编程语言或框架choice_type.

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

Chr*_*att 7

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

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)
Run Code Online (Sandbox Code Playgroud)

从可维护性的角度来看,这不仅更好(编程语言确实发生了变化:新的变体出现了,旧的模型消失了),但它也为查询提供了更大的灵活性.

然后,您只需为您ModelForm的类别添加一个字段:

class UserProfileForm(forms.ModelForm):
    ...
    category = forms.ModelChoiceField(queryset=ProgrammingCategory.objects.all(), required=False)
Run Code Online (Sandbox Code Playgroud)

而且,在您的表单中,您最终会得到一个包含完整类别列表的选择,另一个包含完整语言列表.然后,您只需要一些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()
Run Code Online (Sandbox Code Playgroud)

的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);
});
Run Code Online (Sandbox Code Playgroud)