0

我有一个具有多对多字段的模型,它通过具有布尔值的表链接该字段。

我在不同的场景中得到了这个,让我们将用户作为主要模型,将兴趣作为多对多字段,将 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')

现在基于上面的模型,当我尝试从 User 模型创建 ModelForm 时,我会对 MultiSelect 字段产生兴趣,这是完全正确的。但是,在我的情况下,我希望表单收集用户兴趣 + 为每个兴趣,如果他想要 join_mail_list 以获得该特定兴趣。请指教?

4

2 回答 2

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">
[...]

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

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

于 2013-08-25T17:41:34.547 回答
0

这个问题有点笼统,但我想说,因为它是一个布尔字段,而不是一个多选字段,所以你有两个 - 一个用于“我感兴趣的事物......”(真)和一个用于“事物的我对……不感兴趣”(错误)。这两个字段都可以从同一个项目列表中进行多选,但这种分隔允许用户应用布尔字段而无需注意。另外,我强烈推荐 jQuery UI 自动完成,这似乎是这里的最佳选择。

更新的答案:

因此,查看您的代码有助于清除一些事情。我这样做的方式就像我最初建议的那样,但稍作调整。

为每个“兴趣”设置一个时事通讯复选框很笨拙,因为它要求用户检查“兴趣”两次——一次是因为他对它感兴趣,一次是因为他想要关于它的电子邮件。所以你必须自动假设用户想要收到他感兴趣的主题的电子邮件,但如果他们愿意,允许他们阻止它。

考虑到这一点,您构建了两个长文本输入,并使用标记系统来实现它们(这是一个很好的,这里还有更多)。第一个输入是“我感兴趣”,第二个输入是“我想收到关于...的电子邮件”。然后,您使用 jQuery 添加一个事件监听器,以确保对于添加到第一个输入的每个标记,它也会自动添加到第二个输入。然后,如果用户不想收到特定主题(或所有主题)的电子邮件,他可以轻松地将其从第二个输入中删除(这对第一个没有任何影响)。

举个例子,这里有一个 jsfiddle,它展示了如何使用 selected-jQuery 库实现这一点。我使用国家和运输,因为我在所选图书馆网站上有一个预先制作的列表,所以我只是从那里复制它。正如您所看到的,这是一个非常简单的 jQuery 代码,您可以轻松地将其应用于任何其他标记系统(非常感谢出色的 Raúl Juárez,他帮助我自己解决了这个问题):

$(".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');
});
于 2013-08-25T17:03:06.547 回答