Django Form:在模板中调用外键字段属性
Django Form: Calling foreign key field attributes in template
在模板中,我想调用外键表单字段的 class 属性 item.pid,如下所示
{%for item in form.item %}
{{item.pid}}
{% endfor %}
我的问题很简单,解决方案也应该很简单,但我现在被困在这里太久了。我已经尝试过 formsets、inlineformsets、clean 以及文档中和此处关于 SO 的更多内容。
甚至无法调用表单字段的 class 方法。
调用 {{form.instance.item.pid}} 应该是解决方案,但我无法得到它 运行.
model.py
class Event(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE, blank=True, null=True, default=0)
item = models.ForeignKey(Item, on_delete=models.CASCADE, blank=True, null=True, default=0)
#many more
class Person(models.Model):
person_number = models.IntegerField(null=True)
name = models.CharField(max_length=200, null=True)
surname = models.CharField(max_length=200, null=True)
#many more
class Item(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE, blank=True, null=True, default=0)
pid = models.IntegerField(null=True)
#many more
def save(self, *args, **kwargs):
self.pid = Person.objects.filter(surname=self.person.surname, name=self.person.name).values("person_number")
super(Item, self).save(*args, **kwargs)
views.py
def event(request, event_id=None):
if event_id:
instance = get_object_or_404(Event, pk=event_id)
else:
instance = Event()
form = EventForm(request.POST or None, instance=instance)
if request.POST and form.is_valid():
form.save()
return HttpResponseRedirect(reverse('cal:calendar'))
context = {
'form': form,
}
return render(request, 'cal/event.html', context)
forms.py
class EventForm(ModelForm):
class Meta:
model = Event
fields = ('person', 'item', 'manymore',)
自定义 FK 字段的选择非常简单。
我几个小时前就完成了这项工作,我使用缓存的方法来完成,这样就不会每次都访问数据库来生成列表。
所以我有一个 Currency
table,我想让申请人选择与其申请相关的货币;
class ApplicationForm(forms.ModelForm):
""" Application form """
currency = forms.ChoiceField(
choices=[]
)
class Meta:
""" Setup the form """
fields = (
...
'currency',
...
)
model = Application
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['currency'].choices = get_currency_choices()
def clean(self):
"""
Custom form cleaning
"""
cleaned_data = super().clean()
currency_id = cleaned_data.get('currency')
cleaned_data['currency'] = Currency.objects.get(id=currency_id)
因此,正如您在此表单中所见,currency
字段从 get_currency_choices
中获取选择。对于外键,您还需要有一个相关模型的实例来保存该关系,因此在 clean
中,我通过 ID 获取与选择相关的实例,该 ID 是表单中字段的值。
选项是从相关模型生成的,并使用以下方法存储在缓存中;
def get_currency_choices():
""" Get currency choices, from cache if possible """
currency_choices = cache.get(CACHED_CURRENCY_KEY)
if not currency_choices:
currencies = Currency.objects.values('id', 'symbol', 'code')
currency_choices = list()
currency_choices.append((None, '')) # I use this so that there isn't a default choice & people can't make the wrong choice by leaving the default value.
for currency in currencies:
currency_choices.append(
(currency['id'], f"{currency['symbol']} ({currency['code']})")
)
cache.set(
CACHED_CURRENCY_KEY, currency_choices, CACHED_CURRENCY_LENGTH
)
return currency_choices
在模板中,我想调用外键表单字段的 class 属性 item.pid,如下所示
{%for item in form.item %}
{{item.pid}}
{% endfor %}
我的问题很简单,解决方案也应该很简单,但我现在被困在这里太久了。我已经尝试过 formsets、inlineformsets、clean 以及文档中和此处关于 SO 的更多内容。 甚至无法调用表单字段的 class 方法。
调用 {{form.instance.item.pid}} 应该是解决方案,但我无法得到它 运行.
model.py
class Event(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE, blank=True, null=True, default=0)
item = models.ForeignKey(Item, on_delete=models.CASCADE, blank=True, null=True, default=0)
#many more
class Person(models.Model):
person_number = models.IntegerField(null=True)
name = models.CharField(max_length=200, null=True)
surname = models.CharField(max_length=200, null=True)
#many more
class Item(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE, blank=True, null=True, default=0)
pid = models.IntegerField(null=True)
#many more
def save(self, *args, **kwargs):
self.pid = Person.objects.filter(surname=self.person.surname, name=self.person.name).values("person_number")
super(Item, self).save(*args, **kwargs)
views.py
def event(request, event_id=None):
if event_id:
instance = get_object_or_404(Event, pk=event_id)
else:
instance = Event()
form = EventForm(request.POST or None, instance=instance)
if request.POST and form.is_valid():
form.save()
return HttpResponseRedirect(reverse('cal:calendar'))
context = {
'form': form,
}
return render(request, 'cal/event.html', context)
forms.py
class EventForm(ModelForm):
class Meta:
model = Event
fields = ('person', 'item', 'manymore',)
自定义 FK 字段的选择非常简单。
我几个小时前就完成了这项工作,我使用缓存的方法来完成,这样就不会每次都访问数据库来生成列表。
所以我有一个 Currency
table,我想让申请人选择与其申请相关的货币;
class ApplicationForm(forms.ModelForm):
""" Application form """
currency = forms.ChoiceField(
choices=[]
)
class Meta:
""" Setup the form """
fields = (
...
'currency',
...
)
model = Application
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['currency'].choices = get_currency_choices()
def clean(self):
"""
Custom form cleaning
"""
cleaned_data = super().clean()
currency_id = cleaned_data.get('currency')
cleaned_data['currency'] = Currency.objects.get(id=currency_id)
因此,正如您在此表单中所见,currency
字段从 get_currency_choices
中获取选择。对于外键,您还需要有一个相关模型的实例来保存该关系,因此在 clean
中,我通过 ID 获取与选择相关的实例,该 ID 是表单中字段的值。
选项是从相关模型生成的,并使用以下方法存储在缓存中;
def get_currency_choices():
""" Get currency choices, from cache if possible """
currency_choices = cache.get(CACHED_CURRENCY_KEY)
if not currency_choices:
currencies = Currency.objects.values('id', 'symbol', 'code')
currency_choices = list()
currency_choices.append((None, '')) # I use this so that there isn't a default choice & people can't make the wrong choice by leaving the default value.
for currency in currencies:
currency_choices.append(
(currency['id'], f"{currency['symbol']} ({currency['code']})")
)
cache.set(
CACHED_CURRENCY_KEY, currency_choices, CACHED_CURRENCY_LENGTH
)
return currency_choices