【问题标题】:How to access to the model through a ModelMultipleChoiceField如何通过 ModelMultipleChoiceField 访问模型
【发布时间】:2017-08-18 17:28:15
【问题描述】:

我的模型中有一个名为“游戏”的多对多字段:

class Team(models.Model):
    name = models.CharField(max_length=15, null=False)
    tag = models.CharField(max_length=4, null=False)
    description = HTMLField(blank=True, null=True)
    logo = models.FileField(upload_to=user_directory_path, validators=[validate_file_extension], blank=True, null=True)
    games = models.ManyToManyField(Games, verbose_name="Jeu", null=False)
    owner = models.ForeignKey(User, verbose_name="Créateur")
    date = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Date de création")
    update = models.DateTimeField(auto_now=True, verbose_name="Dernière modification")

    def __str__(self):
        return self.name

感谢表格,我喂我的模型:

class TeamForm(forms.ModelForm):
    game = Games.objects.all()
    games = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=True, queryset=game)
    logo = forms.ImageField(required=False, widget=forms.FileInput)
    class Meta:
        model = Team
        fields = ('name', 'tag', 'description', 'logo', 'games' )

在我的其他模型“游戏”中,我有一个字段“徽标”。我可以告诉你:

class Games(models.Model):
    guid = models.CharField(max_length=100, unique=True, null=False, verbose_name="GUID")
    title = models.CharField(max_length=100, null=False, verbose_name="Titre")
    logo = models.FileField(upload_to='media/games/', validators=[validate_file_extension], blank=True, null=True, verbose_name="Logo du jeu")
    date = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name="Date de création")
    update = models.DateTimeField(auto_now=True, verbose_name="Dernière modification")
    def __str__(self):
        return self.title

因此,在我的模板中,我可以通过调用 {{form.games}} 来呈现 ManytoMany 字段。 它工作正常,我在任何游戏名称旁边都有很多复选框。

现在,为了更酷,我还想展示游戏的标志。问题是 ModelMultipleChoiceField 只返回 game.id 和 game.title。默认只返回一个元组。

所以我被屏蔽了……

如果您有任何想法,或者如果有人已经遇到过同样的问题,请给我一个解决方案。

非常感谢

有关更多详细信息,我添加了我的 views.py 和我的模板:

def view_team_index(request, id_team):
    if request.user.is_authenticated():
        media = settings.MEDIA

        try:
            team = Team.objects.get(id=id_team)

            if team.owner == request.user:
                owner = True
        except:
            messages.add_message(request, messages.INFO, 'Désolé, cette équipe est inconnue.')
            return redirect(view_wall)

        if request.method == 'POST':

            #Modifier les champs de bases
            if 'request_base' in request.POST:
                request_base = True
                form = TeamForm(instance=Team.objects.get(owner=request.user))

            if 'edit_base' in request.POST:
                form = TeamForm(request.POST, request.FILES, instance=Team.objects.get(owner=request.user))
                if form.is_valid():
                    form.save()

            #Modifier la description
            if 'request_description' in request.POST:
                request_description = True
                form = TeamForm()

            if 'edit_description' in request.POST:
                form = TeamForm(request.POST)

        return render(request, 'team_index.html', locals())
    else:
        messages.add_message(request, messages.INFO, 'Vous devez être connecté pour accéder à cette page.')
        return redirect(view_logon)

模板:

<div class="w3-row-padding margin_bottom_10">
    <div class="w3-col m12">
        <div class="w3-card-2 w3-round w3-white">
            <div class="w3-container w3-padding container">
                <div class="text_align_center">
                    <div><img src="{{media}}{{team.logo|default:"media/images/avatar-default-blue.png"}}" class="w3-circle logo_team" alt="Logo"></div>
                    <form method="POST" action="" enctype="multipart/form-data">
                        {% csrf_token %}
                        <hr>
                        {{form.logo}}
                        <hr>
                        <h4>{{form.name}}</h4>
                        {{form.tag}}
                        <hr>
                        <div class="list">{{form.games}}</div>
                        <hr>
                        <input type="submit" value="Sauvegarder" name="edit_base" class="w3-button w3-theme-d2 w3-margin-bottom">
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

我试图覆盖选择字段,但出现错误:

games = forms.GamesChoiceField(widget=forms.CheckboxSelectMultiple, required=True, queryset=game)
AttributeError: module 'django.forms' has no attribute 'GamesChoiceField'

这是我尝试过的:

from django.forms import ModelMultipleChoiceField

class GamesChoiceField(ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        logo = '<img src="{url}"/>'.format(url=obj.logo.url)
        return "{title} {logo}".format(title=obj.title, logo=logo)

class TeamForm(forms.ModelForm):
    game = Games.objects.all()
    games = forms.GamesChoiceField(widget=forms.CheckboxSelectMultiple, required=True, queryset=game)
    logo = forms.ImageField(required=False, widget=forms.FileInput)
    class Meta:
        model = Team
        fields = ('name', 'tag', 'description', 'logo', 'games' )

让我们看看我目前的工作情况。我只想在每个复选框旁边添加 games.logo。

【问题讨论】:

  • 请添加您的表单和模板示例
  • 您好,表单已添加。这是团队形式。我刚刚添加了更多细节。

标签: python django django-forms


【解决方案1】:

你可以尝试覆盖ModelMultipleChoiceField

from django.forms import ModelMultipleChoiceField


class GamesChoiceField(ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        logo = '<img src="{url}"/>'.format(url=obj.logo.url)
        return "{title} {logo}".format(title=obj.title, logo=logo)


class TeamForm(forms.ModelForm):
    game = Games.objects.all()
    games = GamesChoiceField(widget=forms.CheckboxSelectMultiple, required=True, queryset=game)

更多详情fields-which-handle-relationships

希望对你有帮助

额外信息 替换

games = forms.GamesChoiceField
#     ^^^^

games = GamesChoiceField
#     ^^^^

【讨论】:

【解决方案2】:

您必须手动呈现选择字段。用这个替换{{form.games}}

<select name="games">
    {% for game in form.games_set.all %}
        <option value="{{ game.id }}">{{ game.logo }}</option>
    {% endfor %}
</select>

代码大约是。但概念就是这样。 或许你想使用 jquery/bootstrap 来美化。

另一个主题是您的 ManyToManyField 中的相关名称,如果您想自定义反向查找,请设置它。

【讨论】:

  • 试试 forms.instance.games_set.all
  • Nop.. 没有可显示的内容。谢谢
  • 因为你没有游戏形式。尝试在管理员中检查一些。所以你需要显示游戏模型而不是 form.games 因为它只显示相关。
  • 我至少有一个游戏。当我渲染 {{form.games}} 时,我有所有潜在的游戏要添加。我已经添加了当前的游戏。我通过屏幕截图更新我的帖子以向您展示。
猜你喜欢
  • 2014-12-28
  • 1970-01-01
  • 2019-10-29
  • 2019-08-27
  • 2019-07-23
  • 1970-01-01
  • 2013-06-12
  • 2019-11-25
  • 1970-01-01
相关资源
最近更新 更多