Поле выбора Django в качестве ForeignKey модели в FormSet

У меня есть модели Player и Position. Player ассоциируется с позицией, на которой игрок находится в данный момент. Вы можете назначить игроку новую позицию, вот почему мне это нужно, чтобы использовать ее в некоторой форме. Но в этой форме я вижу, что Position является объектом позиции (см. изображение ниже), но я хотел бы поместить туда "Position.name", чтобы увидеть имя выбора вместо этого объекта, но у меня нет идеи, как это сделать.

Спасибо за помощь.

Position Object

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 ... )

Вернуться на верх