Django 分类选项字段
我在我的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
这两列,这些我已经准备好了。问题是,我不太清楚怎么把一个选项和一个类别关联起来,让用户在创建他们的个人资料时,能够根据choice_type
的选择来挑选编程语言或框架。
我想这可能需要用到一些JavaScript,但这并不是像django代码那样复杂的问题。
1 个回答
14
你需要把这些变成实际的模型,这样你就会有像下面这样的东西:
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);
});