我的 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,它将包含 name 和 choice_type 列,我已经有了。问题是我真的不知道如何将一个选项绑定(bind)到一个类别,并让用户在创建个人资料时根据 choice_type< 中的选择选择一种编程语言或框架。/.
我假设它会涉及一些 JS,但这不像 Django 代码那么严重。
请您参考如下方法:
你会想要制作这些实际的模型,所以你会有这样的东西:
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)
这不仅从可维护性的 Angular 来看更好(编程语言确实在变化:新的出现,旧的消失),而且它还为您提供了更大的查询灵 active 。
然后,您只需在 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);
});
