Reputation: 41
So for forms, if you have quantity = IntegerField() in forms.py, then in the html file you can write {{ form.quantity }} to get the input for the quantity. How can do you the samething for modelformset_factory?
#views.py
#for showing items
if (Items.objects.filter(item_category="Produce").exists()):
produce = Items.objects.filter(item_category="Produce", show=True, quantity__gte=1)
if (Items.objects.filter(item_category="Grains").exists()):
grains = Items.objects.filter(item_category="Grains", show=True, quantity__gte=1)
if (Items.objects.filter(item_category="Protein/Dairy").exists()):
protein_dairy = Items.objects.filter(item_category="Protein/Dairy", show=True, quantity__gte=1)
if (Items.objects.filter(item_category="extras").exists()):
extras = Items.objects.filter(item_category="extra items", show=True, quantity__gte=1)
#playing with formset
form_extras = Items.objects.filter(show=True).count()
formset = modelformset_factory(Cart, form=CustomerOrderForm,extra=form_extras)
form = formset(queryset=Items.objects.none())
if request.method == 'POST':
form = formset(request.POST)
#work on this
if form.is_valid():
print("is valid")
form = formset(request.POST)
instances = form.save(commit=False)
for instance in instances:
#item previously in cart
if (Cart.objects.filter(username=request.user, item_name=form.cleaned_data.get('item_name')).exists()):
cart_instance = Cart.objects.get(username=request.user, item_name=form.cleaned_data.get('item_name'))
cart_instance.quantity = cart_instance.quantity + form.cleaned_data.get('quantity')
cart_instance.save()
else:
#item never in cart, create new instance
item_instance = Items.objects.get(item_name=form.cleaned_data.get('item_name'))
Cart.objects.create(username=request.user, item_name=form.cleaned_data.get('item_name'), weight=item_instance.weight, quantity=form.cleaned_data.get('quantity'), description=item_instance.description, image=item_instance.image, price=item_instance.price, storage_type=item_instance.storage_type, item_category=item_instance.item_category, limit=item_instance.limit,)
timestamp = datetime.date.today()
messages.success(request,"Sucessfully added your items to your cart! " + str(timestamp))
return redirect('/')
else:
print("form not valid for cart")
form = formset()
user_produce_points = request.user.profile.produce_points
user_grain_points = request.user.profile.grain_points
user_protein_dairy_points = request.user.profile.protein_dairy_points
user_extras_points = request.user.profile.extra_items_points
Home.html:
#home.html
<form method="POST">
{% csrf_token %}
{{ form.management_form }}
{{form.as_p}}
<div class="row">
{% for item in produce %}
<div class="card" style="width: 18rem;">
<img src="/media/{{ item.image }}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title text-center">
<b>{% if item.storage_type == "Frozen" %}
Frozen
{% endif %}
{{ item.item_name }} ({{ item.weight }} oz)</b></h5>
<h6 class ="card-title text-center" style="color:green;font-size: 16px;"><b>{{ item.price }} Produce
{% if item.price < 2 %}
Point
{% else %}
Points
{% endif %}
</b></h6>
<p class="card-text">{{ item.description }}</p>
<br><br>
<div class="input-quantity">
<input type="hidden" name="form-{{forloop.counter}}-item_name" value="{{ item.item_name }}">
{{form.quantity}}
{{form.item_name}}
{{form.field}}
Quantity: <input style="max-width:3em;" type="number" name="form-{{forloop.counter}}-quantity" pattern="[0-9]{3}" min="0" max="{{ item.limit }}">
</div>
</div>
</div>
{% endfor %}
<br>
<button type="submit" style="height:38px;" class="btn btn-primary btn-lg sharp" type="button">Add to Cart</button>
</form>
Upvotes: 0
Views: 613
Reputation: 449
Django Docs always has a nice example, it always helps me.
You sadly didn't post (I'm assuming you didn't) the rest of the view function so I can only guess that form
in the template refers to the formset created in the view and that is gets passed. And if it does, you would need to first create the for-loop before accessing it in name="form-{{forloop.counter}}-item_name"
. You could create it like this:
{% for form_line in form %}
<!--form_line rendering you have-->
<p>Form #{{ forloop.counter }}</p>
{{ form_line.quantity }}
{{ form_line.item_name }}
{{ form_line.field }}
{% endfor %}
In your template you also have the produce
variable. I am unsure what that refers to, again, maybe because I can't see the whole view function.
Upvotes: 1