#django #many-to-many #modelform #m2m #create-view
#django #многие ко многим #modelform #m2m #создать-просмотр
Вопрос:
Моя модель области имеет атрибут exercise с ManyToManyField для моей модели Exercise:
class Area(models.Model):
name = models.CharField(max_length=100)
exercise = models.ManyToManyField(Exercise)
class Exercise(models.Model):
name = models.CharField(max_length=100)
В моем AreaView отображается список областей, каждая из которых ссылается на свой собственный список конкретных упражнений, показанный AreaDetailView:
class AreaView(ListView):
model = Area
template_name = 'workouts/areas.html'
class AreaDetailView(DetailView):
model = Area
template_name = 'workouts/exercises.html'
def get_context_data(self, **kwargs):
context = super(AreaDetailView, self).get_context_data(**kwargs)
context['e_form'] = AddExerciseForm
return context
например:
areas.html
- abs
- biceps
- cardio
- legs ...
exercises.html
Abs
- Ab-wheel
- Cable-crunch
- Plank ...
Biceps
- Barbell curl
- Cable curl
- Dumbbell curl
AreaDetailView также отображает форму, в которой я хотел бы разрешить пользователю создавать свои собственные упражнения, которые будут специфичны для их соответствующей области.
Вот моя форма:
class AddExerciseForm(forms.ModelForm):
class Meta:
model = Exercise
fields = ['name']
Мой шаблон:
<form action="{% url 'exercise_add_new' %}" method="post">
{% csrf_token %}
{{ e_form }}
<button type="submit">Save changes</button>
</form>
Мой URL:
path('exercise-add-new', ExerciseFormView.as_view(), name='exercise_add_new'),
И вот мой CreateView, который должен обрабатывать логику:
class ExerciseFormView(CreateView):
form_class = AddExerciseForm
success_url = '/'
def form_valid(self, form):
form.save()
new_ex = Exercise.objects.latest('id')
area = Area.objects.get(id=1)
area.exercise.add(new_ex)
return super(ExerciseFormView, self).form_valid(form)
Это позволяет мне нормально обновить первый объект в моей модели области, но мне нужно настроить значение переменной area
, form_valid
чтобы обновить текущий «идентификатор». Например, если я нажму на «Бицепс», а затем заполню форму, я хочу добавить упражнение, связанное с «id = 2»
Я пробовал area = Area.objects.get(id=self.kwargs['id'])
и другие подобные варианты, но пока ничего из того, что я пробовал, не сработало
Ответ №1:
В ExerciseFormView
вы пытаетесь добавить новое упражнение в область или создать новую область?
При добавлении нового упражнения вам нужно будет передать area-id
URL
что-то вроде add_exercise/<area_id>
, если делать последнее, это должно быть просто.
У вас есть area-id
URL-адрес, который вы можете сделать, как показано ниже
path('exercise-add-new/<int:area_id>/', ExerciseFormView.as_view(),
name='exercise_add_new')
Затем обновите свой view
, как показано ниже
def form_valid(self, form):
form.save()
area = Area.objects.get(pk=self.kwargs["area_id"])
new_ex = Exercise.objects.latest('id')
area.exercise.add(new_ex)
return super(ExerciseFormView, self).form_valid(form)
Также обновите шаблон как :
<form method="post">
{% csrf_token %}
{{ e_form }}
<button type="submit">Save changes</button>
</form>
Комментарии:
1. Привет @Coderaemon спасибо за ваш ответ. Я пытаюсь добавить новое упражнение в область, которая уже существует. Я обновил свой вопрос, чтобы показать свои самые последние усилия
2. Я обновил свой ответ. Пожалуйста, проверьте и дайте мне знать, работает ли это.
3. Отлично! Мне просто нужно было вернуть действие обратно в форму вместе с
area.id
, и оно работает правильно. Большое спасибо за вашу помощь