Reputation: 141
I am creating a Calorie Log website using Django. One creates an account, and can start logging the amount of calories he consumed and burnt on a particular date, then it shows whether on that day he consumed or burnt more calories.
The User can store frequently eaten food and frequent exercise that he does so that when he adds the data he can use that item
Using the given midels user can add food-item and exercises.
Food Model:
class Food(models.Model):
customer = models.ForeignKey(Customer, null=True, on_delete=models.CASCADE)
food_name = models.CharField(max_length=50, null=True, blank=True)
calories = models.IntegerField(null=True)
food_pic = models.ImageField(default="default_food.jpg", null=True, blank=True)
def __str__(self):
return f"{self.food_name}"
Exercise Model:
class Exercise(models.Model):
customer = models.ForeignKey(Customer, null=True, on_delete=models.CASCADE)
exercise_name = models.CharField(max_length=100, null=True, blank=True)
calories = models.IntegerField(null=True)
exercise_pic = models.ImageField(default="default_exercise.png", null=True, blank=True)
def __str__(self):
return f"{self.exercise_name}"
I use the following two models to store the information about a particular date:
DailyFood Model:
class DailyFood(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True)
food_name = models.ForeignKey(Food, on_delete=models.CASCADE, null=True)
quantity = models.FloatField(null=True)
date = models.DateField(auto_now_add=True, null=True)
def __str__(self):
return f"{self.customer}, {self.date}"
DailyExercise Model:
class DailyExercise(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True)
exercise_name = models.ForeignKey(Exercise, on_delete=models.CASCADE, null=True)
quantity = models.FloatField(null=True) # number of hours done exercise
date = models.DateField(auto_now_add=True, null=True)
def __str__(self):
return f"{self.customer}, {self.date}"
IN views.py file
def addData(request):
customer = request.user.customer
food_formset = inlineformset_factory(Customer, DailyFood, fields=('food_name', 'quantity', ))
exercise_formset = inlineformset_factory(Customer, DailyExercise, fields=('exercise_name', 'quantity', ))
f_formset = food_formset(instance=customer)
e_formset = exercise_formset(instance=customer)
if request.method == "POST":
f_formset = food_formset(request.POST, instance=customer)
e_formset = exercise_formset(request.POST, instance=customer)
if f_formset.is_valid():
mf_formset = f_formset.save(commit=False)
mf_formset.customer = customer
mf_formset.save()
else:
return HttpResponse("reached food_formset is not valid")
if e_formset.is_valid():
me_formset = e_formset.save(commit=False)
me_formset.customer = customer
me_formset.save()
return redirect('/')
else:
return HttpResponse("reached exercise_formset is not valid")
else:
foods = Food.objects.filter(customer=customer)
exercises = Exercise.objects.filter(customer=customer)
context = {'foods': foods, 'exercises': exercises, 'f_formset': f_formset, 'e_formset': e_formset}
return render(request, 'cc/add-data.html', context)
AddData html (form section):
<form action="" method="POST">
{% csrf_token %}
<div class="foods">
<p class="ad-accordion">Calories Consumed</p>
<div class="ad-accordion-content">
{% for form in f_formset %}
{{form}}
<br>
{% endfor %}
</div>
</div>
<div class="exercises">
<p class="ad-accordion">Calories Burnt</p>
<div class="ad-accordion-content">
{% for form in e_formset %}
{{form}}
<br>
{% endfor %}
</div>
</div>
<p class="center-button">
<button type="submit">Submit</button>
</p>
</form>
Q) When submitting the form, the form is invalid, when I print the f_formset and e_formset I get:
(Hidden field TOTAL_FORMS) This field is required. (Hidden field INITIAL_FORMS) This field is required. input type="hidden" name="dailyfood_set-TOTAL_FORMS" id="id_dailyfood_set-TOTAL_FORMS"
input type="hidden" name="dailyfood_set-INITIAL_FORMS" id="id_dailyfood_set-INITIAL_FORMS"
input type="hidden" name="dailyfood_set-MIN_NUM_FORMS" id="id_dailyfood_set-MIN_NUM_FORMS"
input type="hidden" name="dailyfood_set-MAX_NUM_FORMS" id="id_dailyfood_set-MAX_NUM_FORMS"
Why are these values not there, I used inlineformset in another project and these values were autofilled by django, but for some reason it does not happen with one??
Upvotes: 4
Views: 1089
Reputation: 1445
When you render a formset manually, you need to include the ManagementForm with the tag {{ your_formset.management_form }}
. This form is used by the formset to manage the collection of forms contained in the formset. See documentation here and here.
<form action="" method="POST">
{% csrf_token %}
<div class="foods">
<p class="ad-accordion">Calories Consumed</p>
<div class="ad-accordion-content">
{{ f_formset.management_form }}
{% for form in f_formset %}
{{form}}
<br>
{% endfor %}
</div>
</div>
<div class="exercises">
<p class="ad-accordion">Calories Burnt</p>
<div class="ad-accordion-content">
{{ e_formset.management_form }}
{% for form in e_formset %}
{{form}}
<br>
{% endfor %}
</div>
</div>
<p class="center-button">
<button type="submit">Submit</button>
</p>
</form>
Upvotes: 4