Как я могу успешно реализовать отношения "многие ко многим" между двумя моделями в моем проекте на django?

после того как я сделал проект с помощью flask и sqlite я хочу сделать его с помощью django у меня получилось добавить продукты к определенной дате

и подсчитывает общее количество калорий, но я не могу показать дни с общим количеством калорий на главной странице, я показываю только дни, которые я добавил в мою модель, но не могу показать ее детали из общего количества белков и жиров и калорий, поэтому я хочу

Урегулирование в функции create_date в моем представлении

и вот детали моего проекта

сначала моя модель

from django.db import models
from datetime import datetime

# Create your models here.
class Food(models.Model):
    name=models.CharField(max_length=512,unique=True)
    protein=models.IntegerField(null=False)
    carbohydrates=models.IntegerField(null=False)
    fats=models.IntegerField(null=False)
    calories=models.IntegerField(null=True)
    def total_calories_food(self):
        total=self.protein * 4 + self.carbohydrates * 4 + self.fats * 9
        self.calories=total
        self.save()



    def __str__(self):
        return f'{self.name}'
class Dates(models.Model):
    food=models.ManyToManyField(Food,through='DatesFoods')
    date=models.DateField()


class DatesFoods(models.Model):
    date_id=models.ForeignKey(Dates,on_delete=models.CASCADE)
    food_id=models.ForeignKey(Food,on_delete=models.CASCADE)


second my forms:
from django import forms
from .models import Food, Dates


class Food_Form(forms.ModelForm):
    class Meta():
        model = Food
        fields = ('name', 'protein', 'carbohydrates', 'fats')


class Dates_Form(forms.ModelForm):
    class Meta():
        model = Dates
        fields = ('date',)
and finally my views

def create_date(request):

    form=Dates_Form(request.POST)
    dates = Dates.objects.all()
     if form.is_valid():
        form.save()
        return render(request,'foodlist/home.html',context={'form':form,'dates':dates,
                                                              })
def add_food(request):
    form=Food_Form(request.POST)
    if form.is_valid():
        form.save()
    foods=Food.objects.all()
    for d in foods:
        d.total_calories_food()

    return render(request,'foodlist/add_food.html',context={'form':form,'foods':foods})


def view_foods_day(request,date):

    d=get_object_or_404(Dates,date=date)
    print(d)
    foods=Food.objects.all()
    foods_day=DatesFoods.objects.filter(date_id=d.id)


    protein=[]
    fats=[]
    carbohydrates=[]
    calories=[]
    for i in foods_day:

        protein.append(i.food_id.protein)
        fats.append(i.food_id.fats)
        carbohydrates.append(i.food_id.carbohydrates)
        calories.append(i.food_id.calories)

    if request.method=='POST':

        food_w=request.POST.get('food-select')

        f=Food.objects.get(pk=food_w)


        DatesFoods.objects.create(date_id=d,food_id=f)


    return render(request,'foodlist/day.html', context={'foods':foods,'date':d.date,
                                                        'protein':sum(protein),
                                                        'fats':sum(fats),
                                                        'carbohydrates':sum(carbohydrates),
                                                        'calories':sum(calories),
                                                        'foods_day':foods_day})

я стараюсь показать все дни с подробным описанием белков, жиров, углеводов в граммах с общим количеством калорий

у меня получилось показать детали для определенного дня, но не для всех дней

Вот решение, которое включает в себя обновление представления для передачи общей информации о питании.

def create_date(request):
    form = Dates_Form(request.POST or None)

    if form.is_valid():
        form.save()

    dates_with_totals = []
    dates = Dates.objects.all()

    for date in dates:
        foods_day = DatesFoods.objects.filter(date_id=date.id)
        total_protein = foods_day.aggregate(Sum('food_id__protein'))['food_id__protein__sum'] or 0
        total_fats = foods_day.aggregate(Sum('food_id__fats'))['food_id__fats__sum'] or 0
        total_carbohydrates = foods_day.aggregate(Sum('food_id__carbohydrates'))['food_id__carbohydrates__sum'] or 0
        total_calories = foods_day.aggregate(Sum('food_id__calories'))['food_id__calories__sum'] or 0

        dates_with_totals.append({
            'date': date,
            'total_protein': total_protein,
            'total_fats': total_fats,
            'total_carbohydrates': total_carbohydrates,
            'total_calories': total_calories
        })

    return render(request, 'foodlist/home.html', context={
        'form': form,
        'dates_with_totals': dates_with_totals,
    })

Надеюсь, это немного поможет вам.

Неясно, какую функцию просмотра вы используете.

Простой пример:

# view.py
def view(reuqest, **kwargs):
  obj = Dates.objects.get(date={date value})
  context = {'object': obj}
  return render(request, {template}, context}
# templates
{% for food in objects.food.all %}
<pre>
food.name: {{ food.name }}
food.prtein: {{ food.prtein }}
food.fats: {{ food.fats }}
food.calories: {{ food.calories }}
food.total_calories_food: {{ food.total_calories_food }}
</pre>
{% endfor %}
Вернуться на верх