Home > database >  how to request and post an object to a foreignkey field
how to request and post an object to a foreignkey field

Time:03-04

When I do this exactly as provided below, a shipping address object is created without the customer assigned in the shipping address foreignkey field, I can add it from the admin panel manually but I'm not able to make it work through code, idk what I'm doing wrong, please help!

**models.py**

class Customer(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, blank=True, null=True)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField(max_length=150)

class ShippingAddress(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
    address_one = models.CharField(max_length=200)
    address_two = models.CharField(max_length=200)
    ...

**views.py**
    
def checkout(request):

    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(customer=customer, complete=False)
        items = order.orderitem_set.all()
    else:
        items = []
        order = {'get_cart_total': 0, 'get_cart_items': 0}


    if request.method == 'POST':
        form = ShippingForm(request.POST)

        if form.is_valid():

            #how do I get the customer to get added in the foreignkey field for the shipping address model

            form.save()
            return redirect('store:checkout_shipping')
        else:
            form = ShippingForm()

    else:
        form = ShippingForm()

    context = {"items": items, "order": order, "form": form}
    return render(request, 'store/checkout.html', context)

CodePudding user response:

In response to your comment #how do I get the customer to get added... etc, in the case that your ShippingForm() points to your ShippingAddress model, or at least something with a customer foreign key field, you may need to do something like this:

def checkout(request):

    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(customer=customer, complete=False)
        items = order.orderitem_set.all()
    else:
        items = []
        order = {'get_cart_total': 0, 'get_cart_items': 0}


    if request.method == 'POST':
        form = ShippingForm(request.POST)

        if form.is_valid():
            new_shipment = form.save(commit=False)
            new_shipment.customer = customer
            new_shipment.save()
            return redirect('store:checkout_shipping')
        else:
            form = ShippingForm()

    else:
        form = ShippingForm()

    context = {"items": items, "order": order, "form": form}
    return render(request, 'store/checkout.html', context)   

Using commit=False on the form.save() will allow you to subsequently modify other fields, in this case, by adding the customer relation, then saving it. More information here in the Django documentation. Salient quote:

This save() method accepts an optional commit keyword argument, which accepts either True or False. If you call save() with commit=False, then it will return an object that hasn’t yet been saved to the database. In this case, it’s up to you to call save() on the resulting model instance. This is useful if you want to do custom processing on the object before saving it, or if you want to use one of the specialized model saving options. commit is True by default.

"Custom processing" in this case is the creation of the foreign key relationship to the model instance (customer).

  • Related