代码之家  ›  专栏  ›  技术社区  ›  Jordan Dovey

如何在django中的表单上显示更多对象信息

  •  1
  • Jordan Dovey  · 技术社区  · 3 年前

    这是这个问题的后续问题: How to pass user object to forms in Django

    这是我的表格:

    class SellForm(forms.Form):
        symbol = forms.ModelChoiceField(queryset=None, widget=forms.Select(attrs={
            'class': 'form-control',
            'placeholder': 'Symbol',
            'autofocus': 'autofocus',
            }))
        
        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request')
            super(SellForm, self).__init__(*args, **kwargs)
            self.fields['symbol'].queryset = Holdings.objects.filter(student=self.request.user.student)
    

    此表单为我提供了以下下拉列表: the example of the dropdown that this form creates

    我在模型中有额外的信息,即每股的购买价格,有没有办法把它也写在表格上?它必须是不可编辑的,尽管这是购买股票的价格。

    以下是表单从中获取数据的模型:

    class Holdings(models.Model):
        student = models.ForeignKey(Student, on_delete=models.CASCADE)
        symbol = models.CharField(max_length=10)
        purchase_price = models.DecimalField(max_digits=10, decimal_places=2)
        
        class Meta:
            verbose_name_plural = "Holdings"
            ordering = ['symbol']
        
        def __str__(self):
            return self.symbol
    

    如果可能的话,我将非常感谢任何帮助!非常感谢。

    3 回复  |  直到 3 年前
        1
  •  2
  •   willeM_ Van Onsem    3 年前

    最简单的方法就是覆盖 __str__ 方法,并包括购买价格:

    class Holdings(models.Model):
        student = models.ForeignKey(Student, on_delete=models.CASCADE)
        symbol = models.CharField(max_length=10)
        purchase_price = models.DecimalField(max_digits=10, decimal_places=2)
    
        class Meta:
            verbose_name_plural = "Holdings"
            ordering = ['symbol']
    
        def __str__(self):
            return f'{self.symbol} ({self.purchase_price})'

    通过以下方式可以更有效地进行过滤:

    class SellForm(forms.Form):
        symbol = forms.ModelChoiceField(
            queryset=None,
            widget=forms.Select(
                attrs={
                    'class': 'form-control',
                    'placeholder': 'Symbol',
                    'autofocus': 'autofocus',
                }
            ),
        )
    
        def __init__(self, *args, request, **kwargs):
            super(SellForm, self).__init__(*args, **kwargs)
            self.fields['symbol'].queryset = Holdings.objects.filter(
                student__user=self.request.user
            )

    因为这将阻止查询获取 Student 对象,或者我们可以使用:

    class SellForm(forms.Form):
        symbol = forms.ModelChoiceField(
            queryset=None,
            widget=forms.Select(
                attrs={
                    'class': 'form-control',
                    'placeholder': 'Symbol',
                    'autofocus': 'autofocus',
                }
            ),
        )
    
        def __init__(self, *args, request, **kwargs):
            super(SellForm, self).__init__(*args, **kwargs)
            self.fields['symbol'].queryset = Holdings.objects.filter(
                student_id=self.request.user.student_id
            )
        2
  •  0
  •   Jordan Dovey    3 年前

    在副驾驶的帮助下,我设法使它工作起来。

    这是一行额外的代码,因此表单现在看起来如下:

    class SellForm(forms.Form):
        symbol = forms.ModelChoiceField(queryset=None, widget=forms.Select(attrs={
            'class': 'form-control',
            'placeholder': 'Symbol',
            'autofocus': 'autofocus',
            }))
        
        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request')
            super(SellForm, self).__init__(*args, **kwargs)
            self.fields['symbol'].queryset = Holdings.objects.filter(student=self.request.user.student)
            self.fields['symbol'].label_from_instance = lambda obj: "%s ($%s)" % (obj.symbol, Holdings.objects.filter(student=self.request.user.student, symbol=obj.symbol).values_list('purchase_price', flat=True)[0])
    

    这是一个非常可怕的长lambda函数,我真的不明白,但我想好了如何从视图中访问购买价格,然后将该部分(.values_list…)附加到lambda函数上,它就成功了。以下是我所做的,这正是我想要的。

    enter image description here

    感谢您的关注和帮助,希望这也能帮助其他可能陷入困境的人!