I created a form for adding products to an e-Commerce site. The form isn’t working perfectly.
First issue: I want to store the user automatically by submitting the form. I actually want to store Who did add the product individually.
Second Issues: The image field is not working, the image is not stored in the database.
How can I fix these issues? help me
forms.py:
from django import forms
from .models import Products
from django.forms import ModelForm
class add_product_info(forms.ModelForm):
class Meta:
model = Products
fields = ('product_title','product_image')
model.py:
class Products(models.Model):
user = models.ForeignKey(User, related_name="merchandise_product_related_name", on_delete=models.CASCADE, blank=True, null=True)
product_title = models.CharField(blank=True, null=True, max_length = 250)
product_image = models.ImageField(blank=True, null=True, upload_to = "1_products_img")
views.py:
def add_product(request):
if request.method == "POST":
form = add_product_info(request.POST)
if form.is_valid():
form.save()
messages.success(request,"Successfully product added.")
return redirect("add_product")
form = add_product_info
context = {
"form":form
}
return render(request, "add_product.html", context)
templates:
<form action="" method="POST" class="needs-validation" style="font-size: 13px;" novalidate="" autocomplete="off" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="d-flex align-items-center">
<button type="submit" class="btn btn-outline-dark ms-auto" style="font-size:13px;">Add</button>
</div>
</form>
>Solution :
You need to set the .user of the .instance wrapped in the form to the logged in user (request.user). Furthermore you need to pass both request.POST and request.FILES to the form to handle files.
from django.contrib.auth.decorators import login_required
@login_required
def add_product(request):
if request.method == 'POST':
form = add_product_info(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
messages.success(request, 'Successfully product added.')
return redirect('add_product')
else:
form = add_product_info()
context = {
'form': form
}
return render(request, 'add_product.html', context)
I would also advise not to use null=True nor blank=True, unless a field is really optional. Likely the product_title should not be optional, nor should the user be, since you use CASCADE in case the user is removed.
Note: You can limit views to a view to authenticated users with the
@login_requireddecorator [Django-doc].
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL[Django-doc] to refer to the user model, than to use theUsermodel [Django-doc] directly. For more information you can see the referencing theUsermodel section of the documentation.
Note: Forms in Django are written in PascalCase, not snake_case,
so you might want to rename the model fromtoadd_product_infoProductInfoForm.
Note: normally a Django model is given a singular name, so
Productinstead of.Products