как реализовать ModelChoiceField в Django - PullRequest
2 голосов
/ 19 февраля 2020

Я пытаюсь создать входную выборку из полей модели базы данных, и я пытался использовать 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)

в моем шаблоне форма выглядит как this .. Вид шаблона формы

Я могу выбрать название и сумму сбережений из объекта WeeklySaving, что мне и нужно, но при отправке формы появляется сообщение об ошибке «Имя пользователя» Сохранение "должно быть поплавком. Это означает, что он фактически сохраняет входные данные как «Сохранение имени пользователя» вместо выбранных сохраняемых заголовка и суммы.

Как мне решить эту проблему, пожалуйста, мне нужна помощь. Я все еще новичок в использовании django.

спасибо за вашу помощь.

1 Ответ

0 голосов
/ 19 февраля 2020

В общем, всегда бывает сложно с несколькими формами в одном представлении. Так что, если вы разделите их на 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...