knusperwurst knusperwurst - 7 months ago 47
Python Question

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

Answer

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.

Comments