简体   繁体   English

如何在 Django 中实现 ModelChoiceField

[英]how to implement ModelChoiceField in Django

I am trying to create an input selection from database model fields and I have tried using ModelChoiceField but I keep getting an error I don't know how to solve.我正在尝试从数据库模型字段创建输入选择,并且我尝试使用 ModelChoiceField,但我不断收到错误,我不知道如何解决。 I need help.我需要帮助。

Here are the models这是模型

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()

My Forms.我的表格。

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"]

In my Views.py i have this在我的 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)

I have a fields.py as follows我有一个 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)

in my template the form appears like this.. Form Template View在我的模板中,表单显示如下..表单模板视图

I am able to select the savings title and the amount from the WeeklySaving object which is what I want but when I submit the form it shows the error "Username Saving" must be a float.我可以从 WeeklySaving 对象中选择储蓄标题和金额,这是我想要的,但是当我提交表单时,它显示错误“用户名储蓄”必须是浮点数。 which means it is actually saving the input as 'Username Saving' instead of the selected saving title and amount.这意味着它实际上是将输入保存为“用户名保存”而不是选择的保存标题和金额。

How can I solve this problem please I need help.我该如何解决这个问题,我需要帮助。 I am still new using django.我还是新手,使用 django。

thanks for your help.谢谢你的帮助。

In general, it always gets hard with multiple forms in the same view.一般来说,在同一个视图中使用多个表单总是很困难。 So if you split them into 2 views it would be much easier.因此,如果您将它们拆分为 2 个视图,则会容易得多。 Maybe it is possible to create one object from the other one?也许可以从另一个对象创建一个对象? It is even worse (i think) that both forms do have the field "amount".更糟糕的是(我认为)两种形式都有“金额”字段。 Maybe it is possible to rename one of them.也许可以重命名其中之一。

Another big problem is this: DepositWeeklySaveForm().amount = forms.FloatField and this depwksave_form.fields['amount'] = WeeklySaveDepositAmountModelChoiceField This cannot work.另一个大问题是: DepositWeeklySaveForm().amount = forms.FloatField和这个depwksave_form.fields['amount'] = WeeklySaveDepositAmountModelChoiceField这行不通。 WeeklySaveDepositAmountModelChoiceField should reference a ForeginKey, not a FloatField. WeeklySaveDepositAmountModelChoiceField应引用 ForeginKey,而不是 FloatField。 so add to your models:所以添加到你的模型中:

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

I would recommend changing everything to a class based view eg CreateView and use get_form_kwargs to pass the user.我建议将所有内容更改为基于类的视图,例如CreateView并使用get_form_kwargs传递用户。 Something like就像是

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

Then you can set the field in the forms.py like this:然后你可以像这样在 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