0

enter image description here

I'm currently working on a personal project where in a page (purchases page), there will be the main form (includes product name, product category and product specifications fields).

now, there is a link "Add New Product Category" that activates the modal. This modal includes a separate form.

What you are seeing is the final output or what I want the page to be, i only did that in html, no django coding involve.

My (stupid) question is, how am i going to display BOTH forms? I don't understand how {{form}} works.

I successfully rendered the productCategoryForm in the modal by using the code {{form}} but when I do the same in the second form productDetailsForm it's not rendering or displaying. It's blank. I'm not sure how is this going to work.

Below is my Views.py and Forms.py codes.

Views.py

def addNewProduct(response):

c_form = productCategoryForm(response.POST)
p_form = productDetailsForm(response.POST)

if response.method == "POST":

    if c_form.is_valid():
        a = c_form.cleaned_data["productCategField"]
        b = productCategoryModel(productcategoryCol=a)
        b.save()
    return HttpResponseRedirect("/acctg/purchases/")

    if p_form.is_valid():
        c = p_form.cleaned_data["productNameField"]
        d = productModel(productnameCol=c)
        d.save()
    return HttpResponseRedirect("/acctg/purchases/")


context =  {
    "p_form": p_form,
    "c_form": c_form
}        

return render(response, 'purchases.html', context)

Forms.py

class productCategoryForm(forms.Form):
    productCategField = forms.CharField(label="Product Category", max_length=100, widget= forms.TextInput(attrs={'class':'form-control col-sm-8 col-form-label'}))

class productDetailsForm(forms.Form):   
    productNameField = forms.CharField(label="Product Name", max_length=100, required=True, widget=forms.TextInput(attrs={'placeholder':'Enter Product Name', 'class':'form-control col-sm-8 col-form-label'}))

Models.py

# Create your models here.
class productCategoryModel(models.Model):
    productcategoryCol = models.TextField()

    def __str__(self):
        return self.productcategoryCol

class productModel(models.Model):
    productnameCol = models.TextField()
    productspecsCol = models.TextField()
    #productcategCol = models.ForeignKey(productcategoryCol, default=None, on_delete=models.CASCADE)

    def __str__(self):
        return self.productnameCol

Appreciate your help on this. Thank you!

2 Answers 2

2

You can pass both forms in your template through context.


def addNewProduct(request):
    p_form = productDetailsForm()
    c_form = productCategoryForm()
    if request.method == "POST":
        p_form=productDetailsForm(request.POST)
        if p_form.is_valid():
            p_form.save()
            return redirect("/")
    context =  {
           "p_form": p_form,
           "c_form": c_form
             }
    return render(response, 'purchases.html', context)
    

Now in the template you can render both forms with {{p_form}} and {{c_form}}. And provide different actions and different views for both forms.

EDIT:

If you want to handle both forms with a single view then you can use the name attribute in your submit button inside your template.

template:

  <form method='POST'>
    {{p_form.as_p}}
    <button type="submit" name="btn1">Add Product</button>
    </form>
    

    <form method='POST'>
    {{c_form.as_p}}
    <button type="submit" name="btn2">Add Category</button>
    </form>

Now in the views.

def addNewProduct(request):
    p_form = productDetailsForm()
    c_form = productCategoryForm()
    if request.method=='POST' and 'btn1' in request.POST:
        p_form=productDetailsForm(request.POST)
        if p_form.is_valid():
            p_form.save()
            return redirect("/")
    if request.method=='POST' and 'btn2' in request.POST:
        c_form=productCategoryForm(request.POST)
        if c_form.is_valid():
            c_form.save()
            return redirect("/")
    context =  {
       "p_form": p_form,
       "c_form": c_form
         }
    return render(response, 'purchases.html', context)
Sign up to request clarification or add additional context in comments.

6 Comments

Hello! thanks for your answer. it perfectly solves my problem BUT I noticed in your code that only p_form will be saved. How about the c_form? I tried adding another IF c_form.is_valid() code block but it seems that it's not saving. i have updated my code above.
you can write another view with different action/url for saving c_form same as p_form @BenDaggers
understood! sorry @Arjun, i'm still a newbie trying to learn django thru youtube, dj documentations, stackoverflow and tutorials. This might be a stupid question to you :) but what will be the url of that? my goal is to have 2 forms ('add product category' and 'add new product') in one page.
they have different submit button. see my models.py and forms.py code.
Here above in my answer I have given example to save p_form also with the option to render another c_form. Now for saving c_form you need to write another view same as above with different url and provide this url inside your c_form action. Or if you want it in a single view I'll update the answer.
|
1

To avoid spaghetti code I usually separate the views:

# views.py
def purchases(response):
    form = productCategoryForm()
    detailsForm = productDetailsForm()
    
    return render(response, 'purchases.html', {"form": form, "detailsForm": detailsForm})

@require_POST
def add_category(request):
    form = productCategoryForm(response.POST)

    if form.is_valid():
        a = form.cleaned_data["productCateg"]
        b = productCategory(productCat=a)
        b.save()

        return HttpResponseRedirect("/acctg/purchases/")

@require_POST
def add_product_details(request):
    form = productDetailsForm(response.POST)

    if form.is_valid():
        #  your logic here
        b.save()

        return HttpResponseRedirect("/acctg/purchases/")


# urls.py
path('purchases/', purchases, name='purchases'),
path('add_category/', add_category, name='add_category'),
path('add_product_details/', add_product_details, name='add_product_details'),


# purchases.html
            <form action="{% url 'add_category' %}" method="post">
                {% csrf_token %}
                {{form}}
                <button type="submit" class="btn btn-primary">Submit</button>
            </form>


            <form action="{% url 'add_product_details' %}" method="post">
                {% csrf_token %}
                {{detailsForm}}
                <button type="submit" class="btn btn-primary">Submit</button>
            </form>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.