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" style="font-size: 13px;" novalidate="" autocomplete="off" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div >
<button type="submit" style="font-size:13px;">Add</button>
</div>
</form>
CodePudding user response:
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_required
decorator [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 theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
Note: Forms in Django are written in PascalCase, not snake_case, so you might want to rename the model from
toadd_product_info
ProductInfoForm
.
Note: normally a Django model is given a singular name, so
Product
instead of.Products
CodePudding user response:
why are you using the ForeignKey with your user. the first issue i notice is with the class Meta. Pass this as a list not tuple.
class add_product_info(forms.ModelForm):
class Meta:
model = Products
fields = [
'product_title',
'product_image',
]
then try this as well.
class Products(models.Model):
user = models.OneToOneField(User, related_name="merchandise_product_related_name", on_delete=models.CASCADE, blank=True, null=True)