Поле выбора Django в качестве ForeignKey модели в FormSet
У меня есть модели Player и Position. Player ассоциируется с позицией, на которой игрок находится в данный момент. Вы можете назначить игроку новую позицию, вот почему мне это нужно, чтобы использовать ее в некоторой форме. Но в этой форме я вижу, что Position является объектом позиции (см. изображение ниже), но я хотел бы поместить туда "Position.name", чтобы увидеть имя выбора вместо этого объекта, но у меня нет идеи, как это сделать.
Спасибо за помощь.
models.py
class Position(models.Model):
name = models.CharField(max_length=20)
short = models.CharField(max_length=2)
class Players(models.Model):
name = models.CharField(max_length=200)
positionId = models.ForeignKey(Position, on_delete=models.CASCADE, null=True, blank=True)
forms.py
class CompositionForm(ModelForm):
class Meta:
model = Players
fields = ("positionId", ... many more ... )
table.html
<table id="nominated-player-table" class="table table-bordered" style="">
{% for form in formset.forms %}
{% if forloop.first %}
<thead>
<td colspan="15"
style="background-color: dimgray; color: white; border-top-right-radius: 15px; border-top-left-radius: 15px; border: none">
Nominovaní hráči
</td>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr>
{% for field in form.visible_fields %}
<td>
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
На днях я столкнулся с этим, но с полем ModelChoiceField в обычной форме, а не в ModelForm. Вы подклассифицируете ModelChoiceField, чтобы переопределить генерацию меток выбора. Из документации Django:
from django.forms import ModelChoiceField
class MyModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return "My Object #%i" % obj.id
В вашем случае включите obj.PositionId.name
в метку
Нечто подобное должно быть возможно для ModelForms. Проверьте документацию. Да, modelform_factory имеет аргумент field_classes
, чтобы вы могли переопределить стандартное поле ModelChoiceField
Вам необходимо добавить в свои модели методы magic __str__
или __unicode__
, потому что Django сам не знает, как преобразовать экземпляры моделей в строку, и представляет ее как ModelName object
# In python 2.x you can uncoment next line.
# from __future__ import unicode_literals
class Position(models.Model):
name = models.CharField(max_length=20)
short = models.CharField(max_length=2)
def __unicode__(self):
return self.name
class Players(models.Model):
name = models.CharField(max_length=200)
positionId = models.ForeignKey(
Position, on_delete=models.CASCADE, null=True, blank=True)
def __unicode__(self):
return self.name
Если вам нужно больше песонализации, вы можете использовать label_from_instance
в форме:
class CustomModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return 'The position with name %s' % obj.name
class CompositionForm(forms.ModelForm):
positionId = CustomModelChoiceField(queryset=Position.objects)
class Meta:
model = Players
fields = ("positionId", ... many more ... )