繁体   English   中英

如何在 Django 中实现 ModelChoiceField

[英]how to implement ModelChoiceField in Django

我正在尝试从数据库模型字段创建输入选择,并且我尝试使用 ModelChoiceField,但我不断收到错误,我不知道如何解决。 我需要帮助。

这是模型

class WeeklySavingsDeposit(models.Model):

    WEEKLY_SAVE_DEPOSIT_STATUS_PENDING = 'Pending'
    WEEKLY_SAVE_DEPOSIT_STATUS_APPROVED = 'Approved'
    WEEKLY_SAVE_DEPOSIT_STATUS_DENIED = 'Denied'

    WEEKLY_SAVE_DEPOSIT_STATUS_CHOICES = ((WEEKLY_SAVE_DEPOSIT_STATUS_PENDING, 'Pending'), (WEEKLY_SAVE_DEPOSIT_STATUS_APPROVED, 'Approved'), (WEEKLY_SAVE_DEPOSIT_STATUS_DENIED, 'Denied'))

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateTimeField(default=timezone.now)
    savings_title = models.CharField(max_length=100, null = True, blank=True)
    amount = models.FloatField()
    dep_proof = models.ImageField(upload_to='deposit_proofs')
    status = models.CharField(max_length = 40, choices = WEEKLY_SAVE_DEPOSIT_STATUS_CHOICES, default='Pending')
    dep_tag = models.IntegerField(default=0)


    def __str__(self):
        return f'{self.user.username} WeeklySaveDeposit'
class WeeklySaving(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created = models.DateTimeField(default=timezone.now)
    title = models.CharField(max_length = 100, default = 'Weekly Savings Title')
    duration = models.CharField(max_length=40, choices=WEEKLY_SAVE_DURATION_CHOICES, default ='2 Months')
    completion_date = models.DateTimeField(null=True)
    amount = models.FloatField()
    target_amount = models.FloatField(null=True)
    status = models.CharField(max_length= 40,choices = WEEKLY_SAVE_STATUS_CHOICES, default='Pending')
    week_save_day = models.CharField(max_length =100, choices=WEEKLY_SAVE_DAY_CHOICES, default='Friday')
    amount_saved = models.FloatField()

我的表格。

class StartWeeklySaveForm(forms.ModelForm):

   title = forms.CharField(label = 'Savings Title', required=True)
   amount =  forms.FloatField(label='Amount to Save Weekly? (in Naira):', min_value=WeeklySaving.MIN_WEEKLY_SAVE, max_value=WeeklySaving.MAX_WEEKLY_SAVE, required=True, widget=forms.TextInput(attrs={'placeholder': 'Input the amount you want to save weekly. Minimum 500'}))

   class Meta:
       model = WeeklySaving
       fields = ["title", "amount", "duration", "week_save_day"]


class DepositWeeklySaveForm(forms.ModelForm):
       amount = forms.FloatField(label='Enter Amount in (Naira)', min_value=WeeklySaving.MIN_WEEKLY_SAVE, max_value=WeeklySaving.MAX_WEEKLY_SAVE, required=True, help_text='How much to deposit? Minimum 500',)
   dep_proof = forms.ImageField(label='Upload a Proof of Payment', help_text='teller or transaction receipt as image')

   class Meta:
       model = WeeklySavingsDeposit
       fields =["savings_title", "amount", "dep_proof"]

在我的 Views.py 我有这个

@login_required
def weekly_save(request):
    startwksave_form = StartWeeklySaveForm(request.POST or None, request.FILES)
    depwksave_form = DepositWeeklySaveForm(request.POST or None, request.FILES)
    user=request.user
    depwksave_form.fields['savings_title'] = WeeklySaveDepositModelChoiceField(WeeklySaving.objects.filter(user=user), empty_label="(Select savings)",required=True)
    depwksave_form.fields['amount'] = WeeklySaveDepositAmountModelChoiceField(WeeklySaving.objects.filter(user=user), empty_label="(Select savings amount)",required=True)

我有一个 fields.py 如下


from savings.models import WeeklySaving, WeeklySavingsDeposit
from django.forms import ModelChoiceField


class WeeklySaveDepositModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        result = obj.title
        return str(result)


class WeeklySaveDepositAmountModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        result = obj.amount
        return float(result)

在我的模板中,表单显示如下..表单模板视图

我可以从 WeeklySaving 对象中选择储蓄标题和金额,这是我想要的,但是当我提交表单时,它显示错误“用户名储蓄”必须是浮点数。 这意味着它实际上是将输入保存为“用户名保存”而不是选择的保存标题和金额。

我该如何解决这个问题,我需要帮助。 我还是新手,使用 django。

谢谢你的帮助。

一般来说,在同一个视图中使用多个表单总是很困难。 因此,如果您将它们拆分为 2 个视图,则会容易得多。 也许可以从另一个对象创建一个对象? 更糟糕的是(我认为)两种形式都有“金额”字段。 也许可以重命名其中之一。

另一个大问题是: DepositWeeklySaveForm().amount = forms.FloatField和这个depwksave_form.fields['amount'] = WeeklySaveDepositAmountModelChoiceField这行不通。 WeeklySaveDepositAmountModelChoiceField应引用 ForeginKey,而不是 FloatField。 所以添加到你的模型中:

class WeeklySavingsDeposit(models.Model):
    weekly_savings = models.ForeignKey(WeeklySaving, on_delete=models.CASCADE)
    ...

我建议将所有内容更改为基于类的视图,例如CreateView并使用get_form_kwargs传递用户。 就像是

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

然后你可以像这样在 forms.py 中设置字段:

class DepositWeeklySaveForm(forms.ModelForm):
    weekly_savings = forms.ModelMultipleChoiceField(queryset=None)
    required=True, help_text='How much to deposit? Minimum 500',)
   dep_proof = forms.ImageField(label='Upload a Proof of Payment', help_text='teller or transaction receipt as image')

   class Meta:
       model = WeeklySavingsDeposit
       fields =["savings_title", "amount", "dep_proof", "weekly_savings"]

    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['weekly_savings'].queryset = WeeklySaving.objects.filter(user=user)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM