Django 选择字段作为 FormSet 中的模型 ForeignKey

Django choice field as model ForeignKey in FormSet

我有球员和位置的模型。玩家与玩家当前所在的位置相关联。您可以为玩家分配新位置,这就是为什么我需要它以某种形式使用它。但是在那种形式下,我看到 Position 是 position Object(见下图),但我想把“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 子类化以覆盖选择标签生成。 From the Django docs:

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