Single Dropdown Selected (Brand) Problem (Product edit/update)
DTSREPO opened this issue · 5 comments
Everything fine but when I try to open product form from product list page, Brand not selected.
Template : backend/prod_form.html
Views : backend/product_view.py
I know it's my problem :(
You are creating brands
variable in class level. So, that is like creating a static variable where you need to create instance variables. We discussed about this issue a whole day with examples including small discussion in other days. Your code is:
class CrudProduct(View):
template = 'ecom_app/backend/prod_form.html'
title = 'Product Form'
heading = 'Product Form'
cats = models.Category.objects.all()
brands = models.Brands.objects.all()
suppliers = models.Suppliers.objects.all()
def get(self, request, prod_id=None):
if prod_id:
prod_id = int(prod_id)
prod = models.Product.objects.get(pk=prod_id)
context = {'prod': prod, 'cats': self.cats, 'brands': self.brands, 'suppliers': self.suppliers,
'title': self.title, 'heading': self.heading}
return render(request, self.template, context)
else:
context = {'cats': self.cats, 'brands': self.brands, 'suppliers': self.suppliers, 'title': self.title,
'heading': self.heading}
return render(request, self.template, context)
Look at this part:
class CrudProduct(View):
template = 'ecom_app/backend/prod_form.html'
title = 'Product Form'
heading = 'Product Form'
cats = models.Category.objects.all()
brands = models.Brands.objects.all()
suppliers = models.Suppliers.objects.all()
I told you guys that class level variables are evaluated only once when the interpreter or the system or the module or the class (depending on factors that I discussed with examples) gets loaded. After adding some brands restart the development server with CTRL+C
or CTRL+BREAK)
and you will see your desired result (brands are in the multiple selection on the product entry form).
So, you can refactor it like below:
class CrudProduct(View):
template = 'ecom_app/backend/prod_form.html'
title = 'Product Form'
heading = 'Product Form'
def get(self, request, prod_id=None):
cats = models.Category.objects.all()
brands = models.Brands.objects.all()
suppliers = models.Suppliers.objects.all()
# and the rest goes here
Do the same for post()
too.
But if you want to put them in one place then create the __init__
method in the class.
class CrudProduct(View):
template = 'ecom_app/backend/prod_form.html'
title = 'Product Form'
heading = 'Product Form'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.cats = models.Category.objects.all()
self.brands = models.Brands.objects.all()
self.suppliers = models.Suppliers.objects.all()
# and the rest goes here
def get(self, request, prod_id=None):
# Live in peace here
...
But the later way is not recommended. What if you need a filter with the query inside post or in a later version. Keep your code DRY, but don't be lazy!
@kamruljpi you also take a look at the matter and do not make the same mistake.
To err is human but to avoid such mistakes keep practicing. Keep calm and code with Python. Good luck.
@rubelnl @kamruljpi - I told you to refactor the code, give better reasonable names and append a View
at the end of view
classes. Change CrudProduct
to what we discussed about good naming for scalable projects. Refactor other parts too if there are bad things lurking around.
Edited
class CrudProduct(View):
template = 'ecom_app/backend/prod_form.html'
title = 'Product Form'
heading = 'Product Form'
def get(self, request, prod_id=None):
cats = models.Category.objects.all()
brands = models.Brands.objects.all()
suppliers = models.Suppliers.objects.all()
if prod_id:
prod_id = int(prod_id)
prod = models.Product.objects.get(pk=prod_id)
context = {'prod': prod, 'cats': cats, 'brands': brands, 'suppliers': suppliers,
'title': self.title, 'heading': self.heading}
return render(request, self.template, context)
else:
context = {'cats': cats, 'brands': brands, 'suppliers': suppliers, 'title': self.title,
'heading': self.heading}
return render(request, self.template, context)
Template ...
<select name="brand" class="form-control">
<option value="">--- Select Brand ---</option>
{% with product_brands=prod.brands.all %}
{% for brand in brands %}
<option value="{{ brand.id }}"
{% for b in product_brands %}
{% if b.id == brand.id %}
selected="selected"
{% endif %}
{% endfor %}
>{{brand.name}}</option>
{% endfor %}
{% endwith %}
</select>
Not working ....
Actually it's not my issue,
I mean when open product form from product list page for update or edit product there not selected my previous saved 'Brands Name',
Like first time i was saved product A, Brand B1
and 2nd times i need to edit this same product and change Brand B1 to Brand B2 but B2 should be selected.
@SabujXi