如何在 Django 中更新特定的 manytomany 字段

How to update a specific manytomany field in django

我的 Area 模型有一个带有 ManyToManyField 的 exercise 属性到我的 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 显示了一个区域列表,其中每个 link 都有自己的特定练习列表,由 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 中变量 area 的值,以便当前 'id' 是更新。例如,如果我点击 'Biceps' 然后完成表格,我想添加一个与 'id=2'

相关的练习

我试过area = Area.objects.get(id=self.kwargs['id'])和其他类似的变体,但到目前为止我试过的都没有用

ExerciseFormView中,您是要向某个区域添加新练习还是创建一个新区域?
如果添加新练习,您将必须从 URL 传递 area-id,例如 add_exercise/<area_id>,如果是后者,则应该很简单。

你在 URL 中通过了 area-id 你可以像下面那样做

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>