简体   繁体   中英

“Select a valid choice.” Error using Modelform in Django

I dont understand why i kept getting this error:

"Select a valid choice. That choice is not one of the available choices." The Error Message belongs to the field "account"

Here are my model:

class Account(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    balance = models.FloatField()
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class Entry(models.Model):
    account = models.ForeignKey("Account", on_delete=models.CASCADE)
    amount = models.FloatField()
    expense = models.BooleanField(default=True)
    date = models.DateTimeField()
    usage = models.CharField(max_length=200, blank=True)
    payment_method = models.ForeignKey("PaymentMethod",    on_delete=models.CASCADE)
    category = models.ForeignKey("Category", on_delete=models.CASCADE)

    def __str__(self):
        return "{} - {}".format(self.date, self.account)

My view:

class AddExpenseView(View):
    template_name = "finance/create_booking.html"
    form_class = CreateBookingForm

    @method_decorator(login_required)
    def get(self, request):
        context = {
            "title": "StatYourLife - Neue Ausgabe",
            "create_booking_form": self.form_class(user=request.user)
        }

        return render(request, self.template_name, context)
    @method_decorator(login_required)
    def post(self, request):
        form = self.form_class(request.POST)
        if form.is_valid():
            user_profile = UserProfile.objects.get(user_id=request.user)
            booking = form.save(commit=False)
            account = booking.account
            account.balance -= booking.amount
            booking.expense = True
            booking.date = timezone.now()
            user_profile.entrys += 1
            user_profile.save()
            account.save()
            booking.save()
            return HttpResponseRedirect(reverse("finance:index"))
        else:
            context = {
                "title": "test",
                "create_booking_form": form
            }
            return render(request, self.template_name, context)

and my form:

class CreateBookingForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super(CreateBookingForm, self).__init__(*args, **kwargs)
        self.fields["account"].queryset =     Account.objects.filter(owner=self.user)

    class Meta:
        model = Entry
        exclude = ["expense", "date"]

I works fine until i try to submit this form with an account type selected.

In your post method, you have forgotten to pass the user to the form. Since you set the account field's queryset to Account.objects.filter(owner=self.user) , that means you have a different queryset when you display the form to when you validate the data.

Change it to:

def post(self, request):
    form = self.form_class(request.POST, user=self.request.user)

It might be better to change the form to:

self.user = kwargs.pop('user')

Then you would get an explicit error when user is missing from kwargs .

I also faced this type of error while testing a modelform upon passing account model instance directly to account field. Because the modelform shows the foreign key field as select options. ie. it lists all the account objects as select options with the value account.id and throws error if the account_obj not in avilable choices (list of account ids ( [int] )).

CreateBookingForm(data={'account': Account.objects.first()})

But here, we have to pass the account id instead of the whole account object.

CreateBookingForm(data={'account': Account.objects.first().id})

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.

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