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