gpt4 book ai didi

django - ModelForm 中外键的表单字段,ModelChoiceField 有太多选择?

转载 作者:行者123 更新时间:2023-12-04 17:17:13 26 4
gpt4 key购买 nike

我有一个简单的外键关系,我想在 ModelForm 中使用,但没有 ModelChoiceField。

class Sample(models.Model):
alt = IntegerField(db_index=True, unique=True)

class Assignment(models.Model):
sample = models.ForeignKey(Sample, on_delete=models.CASCADE)
我想让AssignmentForm 根据样本的alt 字段的内容选择样本。使用 ModelChoiceField 它将是这样的:
class SampleSelect(ModelChoiceField):
def label_from_instance(self, obj):
return obj.alt

class AssignmentForm(ModelForm):
sample = SampleSelect(queryset=Sample.objects.all())
class Meta:
model = Assignment
fields = ['sample']
ModelChoiceField documentation说如果选择的数量很大,就用别的东西。

Allows the selection of a single model object, suitable for representing a foreign key. Note that the default widget for ModelChoiceField becomes impractical when the number of entries increases. You should avoid using it for more than 100 items.


我想我需要一个自定义表单字段,但我不知道如何做到这一点。
class SampleBAltField(IntegerField):
def clean(self, value):
try:
return Sample.objects.get(alt=value)
except Sample.DoesNotExist:
raise ValidationError(f'Sample with alt {value} does not exist')
此现有代码应从表单中获取一个整数并将其映射回外键,但我无法弄清楚要覆盖哪些内容以填充来自 Sample 实例的绑定(bind)表单的字段。
ModelForm 中的 FormFields 有没有比较简单的方法可以解决这个问题,还是我需要从头开始编写 Form?

最佳答案

The ModelChoiceField documentation says to use something else if the number of choices is large.


该文档建议使用不同的小部件(否则用户将不得不从包含太多项目的下拉列表中进行选择),但您不一定需要一个完全不同的字段。
如果您希望绑定(bind)表单的字段为 Sample 的 n 个实例,然后 ModelChoiceField还是合适的。
为避免文档中预期的问题,您只需更改该字段的小部件即可。您可能需要确切地决定那是什么。一个简单的选择是使用 NumberInput用户只需输入一个整数作为外键的小部件。
from django.forms.widgets import NumberInput

class AssignmentForm(ModelForm):
sample = ModelChoiceField(queryset=Sample.objects.all(), widget=NumberInput)
class Meta:
model = Assignment
fields = ['sample']

select the sample based on the contents of the sample's alt field


您在这里想要的是与您从文档中引用的内容不同的问题。您可以选择在更改或不更改小部件的情况下实现此功能。
如果希望用户提供 alt值而不是示例的主键,您可以使用 to_field_name ModelChoiceField 的论据(请注意,这仅适用于此处,因为您的 alt 字段是唯一的)
class AssignmentForm(ModelForm):
sample = ModelChoiceField(
queryset=Sample.objects.all(),
widget=NumberInput,
help_text="Enter the alt of the sample",
to_field_name='alt'
)

class Meta:
model = Assignment
fields = ["sample"]
为了在渲染绑定(bind)表单时正确渲染初始值,您可以提供 initial实例化绑定(bind)表单时的关键字参数:
form = AssignmentForm(instance=inst,
initial={'sample': inst.sample.alt})
或者,您可以覆盖 __init__表单实例化时自动执行此操作的方法:
class AssignmentForm(ModelForm):
...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance.pk:
self.initial.update({'sample': self.instance.sample.alt})

关于django - ModelForm 中外键的表单字段,ModelChoiceField 有太多选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68415877/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com