FormView没有在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),您应该使路径不重叠,例如:

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

但是,仅凭逻辑上的知识是不够的,因为它无法将Workout链接到必要的练习,因此您可以将逻辑更改为:

from django.urls import reverse

class ExerciseFormView(CreateView):
    form_class = WorkoutModelForm

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

    def get_success_url(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

...