Django Forms: Как использовать выбранный объект из выпадающего меню?
У меня есть функционирующее выпадающее меню, заполненное некоторыми объектами из базы данных. Когда пользователь выбирает один из них, он должен быть направлен на соответствующую страницу объекта. Каждый объект является "Тренировкой", а каждая тренировка имеет "Упражнения". Это работает, однако я пытаюсь получить соответствующий "id" от объекта, который был выбран пользователем. Ниже я предоставлю представление, шаблон, url и форму.
view.py
@login_required
def routines(request):
"""This view will provide a dropdown list of all of the workouts of a specific user.
Once one is selected, the user will hit a submit button.
After submitted, a new page will show all the exercises for that workout"""
if request.method == "GET":
#if we have a GET response, provide a form with filled data
form = RoutineForm(request.GET, user=request.user)
#data needs to equal the object that was selected from the GET form
data = 1
if form.is_valid():
data=form.cleaned_data("workout")
form.instance.owner = request.user #make sure we have the right user
form.save()
return HttpResponseRedirect('routine_workouts_app:routines')
context = {'form':form, 'data':data}
return render(request, 'routine_workouts_app/routines.html', context)
@login_required
def routine(request, data):
"""I think this is the view that will display the information of a workout as of now.
Should be similar to the workout view."""
a_workout = Workout.objects.get(id=data)
#Make sure the topic belongs to the current user
if a_workout.owner != request.user:
raise Http404
exercises = a_workout.exercise_set.order_by('exercise_name')
context = {'a_workout': a_workout, 'exercises':exercises}
return render(request, 'routine_workouts_app/routine.html', context)
routines.html
<form action="{% url 'routine_workouts_app:routine' data %}" method="get">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Make Workout</button>
</form>
урлы
path('routines/', views.routines, name='routines'), #this one deals with selecting a workout and submitting a form
#via routine/ shows the specific workout. just like workouts/int
path('routines/<int:data>/', views.routine, name='routine'), #this one displays the information based on the form
и forms.py
class RoutineForm(forms.ModelForm):
"""This creates a form to work for Routine making"""
def __init__(self, *args, user=None, **kwargs): #this code helps to manage ownership of workouts.
super().__init__(*args, **kwargs)
self.fields['workout'].queryset = Workout.objects.filter(owner=user)
#info comes from the Routine model. Only field is 'workout' and labels is how we are going to identify the field on the webpage
class Meta:
model = Routine
fields = ['workout']
labels = {'workout': 'Workout'}
В принципе, я хотел бы иметь data
равным объекту, который пользователь выбрал в моей routines
функции в views.py. Оттуда я могу получить ID объекта и направить пользователя на нужную страницу. На данный момент, независимо от того, что выбрал пользователь, он будет направлен на страницу "Workout" с ID 1 (поэтому она функционирует, но не по моему желанию).
Заранее благодарен за помощь. Также, может ли кто-нибудь порекомендовать какие-нибудь учебники, которые помогают улучшить навыки работы с Django, подобные этому?
картинка для справки:
Вы можете использовать сочетание клавиш redirect
, чтобы после проверки формы сделать перенаправление на именованный url с аргументами. Аргументом является id тренировки, который сохраняется в экземпляре рутины, созданной формой.
<form action="{% url 'routine_workouts_app:routines' %}" method="get">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Make Workout</button>
</form>
from django.shortcuts import redirect
@login_required
def routines(request):
form = form = RoutineForm(request.GET or None, user=request.user)
if form.is_valid():
# workout_instance = form.cleaned_data("workout")
routine_instance = form.save(commit=False)
routine_instance.owner = request.user # make sure we have the right user
routine_instance.save()
return redirect('routine_workouts_app:routine', args=(routine_instance.workout.pk,))
context = {'form': form}
return render(request, 'routine_workouts_app/routines.html', context)