【问题标题】:Django options field with categories带有类别的 Django 选项字段
【发布时间】:2012-02-16 12:12:39
【问题描述】:

我的 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

现在,我想做的是有一个表Choices,它有namechoice_type 列,我已经有了。问题是我真的不知道如何将选项与类别联系起来,并让用户在创建个人资料时根据choice_type 中的选择选择编程语言或框架。

我认为它会涉及一些 JS,但这不像 django 代码那么大。

【问题讨论】:

  • 你能稍微扩展一下吗?您想限制用户根据计划从某些类别中进行选择吗?
  • @Thomas 不,恰恰相反。我希望用户能够选择他们有经验的编程语言和框架。 choice_type 将有以下选项:编程语言、标记/脚本语言、框架。所以,我想将某些选择(即name)限制为特定类别(即choice_type)。
  • 您将他们的经验数据存储在哪里?
  • @Thomas 在数据库中。在 myapp_choices 表中。
  • 你并不清楚你想要什么。您是希望根据与计划的亲和性来动态过滤用户可用的选项,还是仅显示按choice_type 分组的列表?

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


【解决方案1】:

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

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);
});

【讨论】:

  • 我需要 15 个代表点来投票支持你的答案,但如果可以的话,我会给它 200 票。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-21
  • 2013-04-18
  • 2021-04-01
  • 2017-06-17
  • 2020-02-09
  • 1970-01-01
相关资源
最近更新 更多