Search code examples
pythondjangoformsmodels

Pass an Object through Django Forms


I'm trying to pass an object through a form, but it is not working for me. In models, my Subscription model has a Customer model reference, and any time I want to create or update a Subscription, I need to include the Customer associated with it.

class Subscription(StripeObject):

    sub_user        = models.ForeignKey(Customer)
    creation_date   = models.DateTimeField(auto_now_add=True)

In my view, I am getting everything I need, and in my template, I am trying to pass the customer object from my view as one of the form input fields.

def profile(request):
    user = request.user.get_full_name()
    menu_group = Recipes.objects.filter(today=True).order_by('-price')
    apartments = Apartment.objects.order_by('apartment')
    plans = Plan.objects.order_by('amount')

    try:
        customer = Customer.objects.get(user=user)
    except Customer.DoesNotExist:
        customer = Customer(stripe_id=user, user=user, account_balance=0, currency="usd")
        customer.save()
        customer = Customer.objects.get(user=user)

    try:
        subscription = Subscription.objects.get(sub_user=customer)
    except Subscription.DoesNotExist:
        subscription = None

    try:
        charge_id = Subscribe.objects.get(user=user)
    except Subscribe.DoesNotExist:
        charge_id = None

    if request.method == "POST":
        form = AddSubscription(request.POST)

        if form.is_valid(): # charges the card
            if subscription is None:
                form.save()
                return HttpResponseRedirect('/subscription/charge/')

            elif subscription.sub_change(form.cleaned_data['weekly_plan']):
                form.save()
                subscription.checked_out = True
                return HttpResponseRedirect('/profile/')

            else:
                form.save()
                subscription.checked_out = False
                return HttpResponseRedirect('/subscription/charge/')
        else:
            return HttpResponseRedirect('/profile/error/')

    else:
        form = AddSubscription()
    return render_to_response("profile.html", {'customer': customer, 'menu_group_list': menu_group, 'subscription': subscription, 'charge_id': charge_id, 'apartments': apartments, 'plans': plans}, context_instance=RequestContext(request))

Template: profile.html

{% with cus=customer %}
<input type="hidden" id="sub_user" name="sub_user" value="{{cus}}">
{% endwith %}

Form:

class AddSubscription(forms.ModelForm):

    sub_user = forms.ModelChoiceField(queryset=Customer.objects.none())

    class Meta:
        model = Subscription
        fields = ['sub_user']

    def __init__(self, *args, **kwargs):
        super(AddSubscription, self).__init__(*args, **kwargs)

The form is apparently not valid. I've already tried using ModelChoiceField, which did not work, and I can confirm both the Subscription and Customer objects I'm working with exist. Any ideas? Has anyone seen this problem before? How can I pass the ForeignKey Customer object through a form?


Solution

  • You're passing a Python object to the template, where Django attempts to render it to HTML and pass it back in the HTTP post. However, neither HTML nor HTTP have any knowledge of what a Customer object is; all you'd get would be the string representation of the object.

    You could fix this by passing the Customer id instead, but there is absolutely no point. You don't need to pass the Customer to and from the form at all; you successfully get it from the request when you instantiate the form on GET, you can do exactly the same on POST.