2013-08-25 137 views
0

我有一个模型与许多字段,它通过一个表与布尔值链接的字段。Django ManyToMany字段使用通过关系值

我在不同的场景中得到了这个,让用户作为主要模型,兴趣作为多对多的字段和user_interest模型作为贯穿模型,在user_interest内部我有一个布尔字段,我希望用户在选择每个字段时指定他的许多很多值,

目前我坚持试图找到一个适当的表单接口,以满足我的需要,目前我正在使用MultipleSelect小部件,它只显示感兴趣的选择,是否有任何示例字段控制会允许我选择兴趣并指定布尔字段的值?如果不是,我的情况下最佳做法是什么?

最好的问候,用代码样本

class Interest(models.Model): 
    name = models.CharField(_('Name'), max_length=200,) 


class UserInterest(models.Model): 
    interest = models.ForeignKey(Interest,) 
    user = models.ForeignKey(getattr(settings, 'AUTH_USER_MODEL'),) 
    join_mail_list = models.BooleanField(default=False) 

class User(models.Model): 
    name = models.CharField(max_length=100) 
    interest = models.ManyToManyField(Interest, through='UserInterest', related_name='user_interest') 

现在基于上述模型

更新的问题,当我尝试创建用户模型的ModelForm,我会得到利益多选场是完全正确。但是,就我而言,如果希望为特定的兴趣join_mail_list,我希望表单为每个兴趣收集用户兴趣+。请指教?

回答

0

这个问题是一种普遍的,但我会说,因为它是一个布尔字段,而不是一个多选字段,所以对于“我感兴趣的东西......”(真)和一个是因为“我对...没有兴趣......”(错误)。这两个字段都会从相同的项目列表中多选,但分离允许用户应用布尔字段而不会发现。另外,我强烈推荐jQuery UI自动完成,看起来就像这里的最佳选择。

更新答案:

所以看到你的代码可以帮助清楚一些事情。我会这样做的方式就像我首先建议的那样,但是稍微调整一下。

为每个'兴趣'设置一个时事通讯复选框是笨拙的,因为它需要用户两次检查'兴趣' - 一次是因为他对它感兴趣,一次是因为他想收到关于它的电子邮件。因此,您必须自动假定用户想让收到他感兴趣的主题的电子邮件,但是如果他们愿意,可以让他们阻止它。考虑到这一点,您需要构建两个长文本输入,并使用标记系统(here's a good one,这里是some more)实现这两个输入。第一个输入是“我感兴趣”,第二个输入是“我想收到关于...的电子邮件”。然后你用jQuery添加一个事件列表器,确保添加到第一个输入的每个标记都会自动添加到第二个标记中。然后,如果用户不想为特定主题(或全部主题)获取电子邮件,他可以轻松将其从第二个输入中取出(这对第一个输入没有任何影响)。

举一个例子,here's a jsfiddle显示了如何使用选择的jQuery库进行操作。我使用了国家和航运,因为我在所选图书馆网站上有一个预先制作的清单,所以我只是从那里复制它。正如你所看到的,这是一个非常简单的jQuery代码,您可以轻松地applicate任何其他标记系统(和许多感谢精细劳尔·华雷斯谁helped me work that out自己):

$(".chosen-select").chosen({disable_search_threshold: 10}); 
$('#countries').on('change', function(e) { 
    var selected = $(this).val(); 
    $.each(selected, function(index, value) { 
     $('#shipping option[value="'+value+'"]:first').prop('selected',true); 
    }); 
    $(".chosen-select").trigger('chosen:updated'); 
}); 
+0

我刚刚更新了我的问题与示例代码,我希望它会进一步澄清我的问题 –

+0

更新我的答案,希望它有帮助。如果你想要的代码示例只是要求=] – yuvi

0

我就假设你想要一个旁边有一个复选框的所有兴趣列表。

假设这些模型:

class Ressource(models.Model): 
    name = models.CharField(max_length=255) 

class Ressource2Village(models.Model): 
    ressource = models.ForeignKey(Ressource) 
    village = models.ForeignKey(Village) 
    amount = models.FloatField() 

class Village(MapObject): 
    name = models.CharField(max_length=255) 

这种形式:

class Ressoure2VilllageForm(forms.Form): 
    name = forms.CharField() 
    # you would use a BooleanField 
    value = forms.IntegerField() 

现在,您可以创建一个表单集(https://docs.djangoproject.com/en/1.5/topics/forms/formsets/):

from django.forms.formsets import formset_factory 
r2v_formset = formset_factory(Ressoure2VilllageForm) 

# use boolean for your case, if you want to edit these values later use n2m to initialize value 
# [{'name': r2v.ressource.name, 'value': r2v.value} for r2v in your_village.ressource2village.all()] 
init_values = [{'name': r.name, 'value': 0} for r in Ressource.objects.all()] 
r2v_formset = r2v_formset(initial=init_values) 

哪个在你的模板会给你:

<label for="id_form-0-name">Name:</label><input type="text" name="form-0-name" value="Kohle" id="id_form-0-name"> 
<label for="id_form-0-value">Value:</label><input type="text" name="form-0-value" value="0" id="id_form-0-value"> 
<label for="id_form-1-name">Name:</label><input type="text" name="form-1-name" value="Eisenerz" id="id_form-1-name"> 
<label for="id_form-1-value">Value:</label><input type="text" name="form-1-value" value="0" id="id_form-1-value"> 
<label for="id_form-2-name">Name:</label><input type="text" name="form-2-name" value="Golderz" id="id_form-2-name"> 
[...] 

与特定用户的关联可以在处理过程中考虑到他的身份验证细节。

显示,验证和处理这应该是非常简单的,随时提出后续问题。