So, i have been having problems filling in the user in a form. My strategy has been validating the form, creating an object, passing the foreign key and the other fields with .cleaned_data and saving the object. More specifically, I basically want to create a "workout" object in the database, adding a name and a description from the form and autofilling the created_by_user field.
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 (I am just adding the workout model)
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']
my template
{% 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>
You can remove 'created_by_user'
from the fields list in your form as you do not need it to display or validating. Then render the form just with {{ form }}
.
You can use save()
method since you use a ModelForm
. Change your view accordignly:
@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)