自动填写表单的外键

问题描述

所以,我在填写用户表单时遇到了问题。我的策略是验证表单、创建对象、使用 .cleaned_data 传递外键和其他字段并保存对象。 更具体地说,我基本上想在数据库中创建一个“锻炼”对象,从表单中添加名称和描述并自动填充 created_by_user 字段。

views.py

@login_required(login_url='login')
def workouts(request,user_id):
    context = {}
    if request.method == 'POST':
        form = WorkoutForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data['name']
            description = form.cleaned_data['description']

            Workout.objects.create(
            created_by_user=request.user,name=name,description=description)

            context = {'name': name,'description': description}

        return render(request,'Trainmate/fill_workout_with_sets.html',context)

    else:
        form = WorkoutForm()
        workout_programs = Workout.objects.all()
        user_workouts = workout_programs.filter(created_by_user=user_id)
        context = {'user_workouts': user_workouts,'form': form}
        return render(request,'Trainmate/workouts.html',context) 

models.py(我只是添加了锻炼模型)

class Workout(models.Model):
    name = models.CharField(max_length=150,null=True)
    created_by_user = models.ForeignKey(User,null=True,on_delete=models.RESTRICT)
    description = models.TextField(max_length=1000,null=True)

    def __str__(self):
        return self.name 

forms.py

class WorkoutForm(forms.ModelForm):
    class Meta:
        model = Workout
        fields = ['name','description','created_by_user']

我的模板

{% extends 'Trainmate/main.html' %}

{% block content %}
<h1>My Workouts</h1>

<div>
    {% for workout in user_workouts %}
        {{ workout.name }}<br>
    {% endfor %}
</div>

<h1>Create new Workout</h1>
<form method="POST" action="">
    {% csrf_token %}
    {{ form.name }}
    {{ form.description }}
    <input type="submit" value="Create Workout">
</form>

解决方法

您可以从表单的字段列表中删除 'created_by_user',因为您不需要它来显示或验证。然后仅使用 {{ form }} 呈现表单。 您可以使用 save() 方法,因为您使用的是 ModelForm。相应地改变你的观点:

@login_required(login_url='login')
def workouts(request,user_id):
    context = {}
    if request.method == 'POST':
        form = WorkoutForm(request.POST)
        if form.is_valid():
            workout = form.save(commit=False)
            workout.created_by_user = request.user
            workout.save()
        
            context = {'name': name,'description': description}
        return render(request,'Trainmate/fill_workout_with_sets.html',context)

    else:
        form = WorkoutForm()
        workout_programs = Workout.objects.all()
        user_workouts = workout_programs.filter(created_by_user=user_id)
        context = {'user_workouts': user_workouts,'form': form}
        return render(request,'Trainmate/workouts.html',context)