django 更新对象IntegrityError,NOT NULL约束失败

bxjv4tth  于 2023-10-21  发布在  Go
关注(0)|答案(1)|浏览(142)

我试图为我的食品跟踪应用程序创建视图,在那里我可以首先选择一个给定的日期,然后将项目添加到FoodLog对象,然而,在选择日期后查看宏工作时,我不能真正添加任何新的其他对象,因为以下错误:
django.db.utils.IntegrityError:NOT NULL约束失败:Copyright © 2018 - 2019 www.foodlog.com版权所有
我想让它首先能够选择一个日期,然后显示FoodLog中的内容,或者能够向其中添加新对象。
我的观点:

def food_log(request):
food_log = None
total_macros = {}

if request.method == 'POST':
    date_form = DateForm(request.POST)
    food_item_form = FoodLogFoodItemForm(request.POST)

    if date_form.is_valid():
        selected_date = date_form.cleaned_data['date']
        food_log, created = FoodLog.objects.get_or_create(user=request.user, date=selected_date)
        total_macros = food_log.calculate_total_macros_log()

    if food_item_form.is_valid():
        food_log_food_item = food_item_form.save(commit=False)
        food_log_food_item.food_log = food_log
        food_log_food_item.save()

else:
    today = timezone.now().date()
    food_log = FoodLog.objects.filter(user=request.user, date=today).first()
    date_form = DateForm(initial={'date': today})

    if food_log:
        total_macros = food_log.calculate_total_macros_log()

food_item_form = FoodLogFoodItemForm()

return render(request, 'food_log.html',
              {'food_log': food_log, 'date_form': date_form, 'food_item_form': food_item_form,
               'total_macros': total_macros})

我拥有的模型:

class FoodLog(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
foods = models.ManyToManyField(FoodItem, blank=True, through='FoodLogFoodItem')
meals = models.ManyToManyField(Meal, blank=True, through='FoodLogMeal')
date = models.DateField()

def calculate_total_macros_log(self):
    log_total_kcal = 0
    log_total_carbohydrates = 0
    log_total_fats = 0
    log_total_proteins = 0

    # Calories and macronutrients from FoodLogFoodItem - divided by 100 as FoodItems have values per 100g
    for food_log_food_item in self.foodlogfooditem_set.all():
        food_item = food_log_food_item.food_item
        quantity = food_log_food_item.quantity
        log_total_kcal += food_item.kcal * quantity/100
        log_total_carbohydrates += food_item.carbohydrates * quantity/100
        log_total_fats += food_item.fats * quantity/100
        log_total_proteins += food_item.proteins * quantity/100

    # Calories and macronutrients from FoodLogMeal - divided by 100 as Meals have values per 100g
    for food_log_meal in self.foodlogmeal_set.all():
        meal = food_log_meal.meal
        meal_macros = meal.calculate_total_macros_meal()
        quantity = food_log_meal.quantity
        log_total_kcal += meal_macros['total_kcal_per_100g'] * quantity/100
        log_total_carbohydrates += meal_macros['total_carbohydrates_per_100g'] * quantity/100
        log_total_fats += meal_macros['total_fats_per_100g'] * quantity/100
        log_total_proteins += meal_macros['total_proteins_per_100g'] * quantity/100

    return {
        'log_total_kcal': log_total_kcal,
        'log_total_carbohydrates': log_total_carbohydrates,
        'log_total_fats': log_total_fats,
        'log_total_proteins': log_total_proteins,
    }

def __str__(self):
    return f"{self.user.username}'s Food Log - {self.date}"

class FoodLogFoodItem(models.Model):
food_log = models.ForeignKey(FoodLog, on_delete=models.CASCADE)
food_item = models.ForeignKey(FoodItem, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)

class FoodLogMeal(models.Model):
food_log = models.ForeignKey(FoodLog, on_delete=models.CASCADE)
meal = models.ForeignKey(Meal, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)

表格:

class DateForm(forms.Form):
date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))

def __init__(self, *args, **kwargs):
    initial_date = kwargs.pop('initial_date', None)
    super().__init__(*args, **kwargs)
    if initial_date:
        self.fields['date'].initial = initial_date

class FoodLogFoodItemForm(forms.ModelForm):
    class Meta:
        model = FoodLogFoodItem
        fields = ['food_item', 'quantity']

class FoodLogMealForm(forms.ModelForm):
    class Meta:
        model = FoodLogMeal
        fields = ['meal', 'quantity']
cqoc49vn

cqoc49vn1#

我使用以下代码解决了这个问题:
查看次数:

def food_log(request):

# Handling the FoodDailyRequirementsForm
try:
    daily_requirements_instance = FoodDailyRequirements.objects.get(user=request.user)
except FoodDailyRequirements.DoesNotExist:
    daily_requirements_instance = None

if 'submit_daily_requirements' in request.POST:
    daily_requirements_form = FoodDailyRequirementsForm(request.POST, instance=daily_requirements_instance)
    if daily_requirements_form.is_valid():
        daily_requirements = daily_requirements_form.save(commit=False)
        daily_requirements.user = request.user
        daily_requirements.save()
        return redirect('food_log')
else:
    daily_requirements_form = FoodDailyRequirementsForm(instance=daily_requirements_instance)

today = timezone.now().date()  # Get today's date

# By default, set selected_date to today's date
selected_date = today

# If the selected date is stored in the session, set selected_date from the session
if 'selected_date' in request.session:
    selected_date_str = request.session['selected_date']
    selected_date = datetime.strptime(selected_date_str, '%Y-%m-%d').date()

# If the date form is submitted, update selected_date
if 'submit_date' in request.POST:
    date_form = DateForm(request.POST)
    if date_form.is_valid():
        selected_date = date_form.cleaned_data['date']
        request.session['selected_date'] = selected_date.strftime('%Y-%m-%d')  # save in session
        return redirect('food_log')
else:
    date_form = DateForm(initial={'date': selected_date})  # Set the form with the selected date

# Fetch or create FoodLog for the selected date
food_log, created = FoodLog.objects.get_or_create(user=request.user, date=selected_date)

# Calculate macronutrients
total_macros = food_log.calculate_total_macros_log()

# Fetch all FoodLogFoodItem and FoodLogMeal objects related to the food_log
food_log_fooditems = FoodLogFoodItem.objects.filter(food_log=food_log)
food_log_meals = FoodLogMeal.objects.filter(food_log=food_log)
food_log_items = list(food_log_fooditems) + list(food_log_meals)
food_log_items.sort(key=lambda x: x.id, reverse=True)

# Handling the FoodItem form submission
if 'submit_fooditem' in request.POST:
    fooditem_form = FoodLogFoodItemForm(request.POST, user=request.user)
    if fooditem_form.is_valid():
        food_item = fooditem_form.save(commit=False)
        food_item.food_log = food_log
        food_item.save()
        return redirect('food_log')
else:
    fooditem_form = FoodLogFoodItemForm(user=request.user)

# Handling the Meal form submission
if 'submit_meal' in request.POST:
    meal_form = FoodLogMealForm(request.POST, user=request.user)
    if meal_form.is_valid():
        meal = meal_form.save(commit=False)
        meal.food_log = food_log
        meal.save()
        return redirect('food_log')
else:
    meal_form = FoodLogMealForm(user=request.user)

return render(request, 'food_log.html',
              {'daily_requirements_form': daily_requirements_form,
               'date_form': date_form,
               'selected_date': selected_date,
               'food_log_items': food_log_items,
               'total_macros': total_macros,
               'fooditem_form': fooditem_form,
               'meal_form': meal_form})

相关问题