如何通过ModelMultipleChoiceField

时间:2017-08-18 17:28:15

标签: python django django-forms

我的模型中有一个叫做“游戏”的ManytoMany字段:

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。 enter image description here

2 个答案:

答案 0 :(得分:0)

您必须手动渲染选择字段。用此替换{{form.games}}

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

代码是aprox。但这个概念就是这样。 也许你想用jquery / bootstrap来美化。

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

答案 1 :(得分:0)

您可以尝试覆盖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
#     ^^^^