我的模型中有一个叫做“游戏”的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' )
答案 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
# ^^^^