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. 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
@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
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. 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.
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. 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. WeeklySaveDepositAmountModelChoiceField
should reference a ForeginKey, not a 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. 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:
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.