FormView 不在 Django 中保存数据

FormView not saving data in Django

我试图让用户通过提交表格来保存特定锻炼的详细锻炼信息。我的 ExerciseDetailView 以我希望的方式显示表单:

class ExerciseDetailView(DetailView):
    model = Exercise
    template_name = 'workouts/types.html'

    def get_context_data(self, **kwargs):
        context = super(ExerciseDetailView, self).get_context_data(**kwargs)
        context['form'] = WorkoutModelForm
        return context

但我的问题是将输入的数据保存在数据库中。我尝试制作 FormView 和 CreateView,但显然遗漏了一些东西:

class ExerciseFormView(FormView):
    form_class = WorkoutModelForm
    success_url = 'workouts:exercise_detail'

    def form_valid(self, form):
        form.save()
        return super(ExerciseFormView, self).form_valid(form)

这是我引用的 WorkoutModelForm:

class WorkoutModelForm(forms.ModelForm):
    class Meta:
        model = Workout
        fields = ['weight', 'reps']

我的模板:

<form action="{% url 'workouts:workout' exercise.id %}" method="post">
    {% csrf_token %}
    {{ form }}
    <button type="submit">Save</button>
</form>

网址:

path('exercise/<int:pk>/detail/', ExerciseDetailView.as_view(), name='exercise_detail'),
path('exercise/<int:pk>/detail/', ExerciseFormView.as_view(), name='workout'),

对于上下文,这里是我的锻炼模型,其中包含一个 get_absolute_url 方法:

class Workout(models.Model):
    weight = models.FloatField(default=0)
    reps = models.PositiveIntegerField(default=0)
    created = models.DateField(auto_now_add=True)
    updated = models.DateField(auto_now=True)
    exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE, default=None)

    def get_absolute_url(self):
        return reverse('exercise_detail', args=[str(self.pk)])

我没有收到任何错误,但是当我提交表单时,我的 url 保持不变,正如我所希望的那样,但是页面只是显示为空白并且没有记录对象。谁能帮我看看是什么问题?

问题不在于你的视图,Django 逻辑永远不会触发这个视图,URL 完全重叠,所以这意味着对于 URL,它总是会触发第一个查看(这里是 ExerciseDetailView),你应该使路径 non-overlapping,例如:

path('exercise/<int:pk>/<b>detail/</b>', ExerciseDetailView.as_view(), name='exercise_detail'),
path('exercise/<int:pk>/<b>workout/</b>', ExerciseFormView.as_view(), name='workout'),

但是触发逻辑是不够的,因为它不会 link Workout 进行必要的练习,您可以将逻辑更改为:

from django.urls import reverse

class ExerciseFormView(<b>CreateView</b>):
    form_class = WorkoutModelForm

    def <b>form_valid</b>(self, form):
        form<b>.instance.exercise_id = self.kwargs['pk']</b>
        return super().form_valid(form)

    def <b>get_success_url</b>(self):
        return reverse('workouts:exercise_detail', kwargs={'pk': self.kwargs['pk']})

需要使用CreateView

from django.views.generic.edit import CreateView

class ExerciseFormView(CreateView):
    form_class = WorkoutModelForm

...