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
...
我试图让用户通过提交表格来保存特定锻炼的详细锻炼信息。我的 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
...