Django CreateView-带有多对多InlineFormset ValueError的ModelForm



我正在努力解决这样一个问题:

我有型号:

class ForecastType(models.Model):
client = models.ForeignKey(Client, related_name="weatherforecast_client")
created_by = models.ForeignKey(Forecaster, related_name="weatherforecast_created_by")
modified_by = models.ForeignKey(Forecaster,
related_name="weatherforecast_modified_by",
blank=True,
null=True)
creation_date = models.DateTimeField(auto_now_add=True)
modification_date = models.DateTimeField(auto_now=True)
weather_forecasts = models.ManyToManyField('WeatherForecast')
STATUS_CHOICES = (
("D", "Draft"),
("A", "Active"),
("H", "History"),
)
status = models.CharField(max_length=1, choices=STATUS_CHOICES, default="D")

class OneDayForecast(ForecastType):
def __str__(self):
return f"Prognoza pogody dla: {self.client}, wykonana dnia: {self.creation_date}"

class WeatherForecast(models.Model):
begin_date = models.DateTimeField(blank=True, null=True)
finish_date = models.DateTimeField(blank=True, null=True)
forecast_type = models.ForeignKey('ForecastType', null=True, blank=True)
description = models.TextField(max_length=300, blank=True, null=True)

我还有ModelForm和InlineFormset:

class OneDayForecastForm(ModelForm):
class Meta:
model = OneDayForecast
exclude = ('weather_forecasts',)
WeatherForecastFormset = inlineformset_factory(OneDayForecast, WeatherForecast, exclude=('forecast_type',), extra=2)

最后是CreateView:

class OneDayForecast(ForecasterRequiredMixin, CreateView):
template_name = "forecaster/one_day.html"
success_url = reverse_lazy("forecaster:dashboard")
model = OneDayForecast
form_class = OneDayForecastForm
def get(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
weather_forecast_form = WeatherForecastFormset()
return self.render_to_response(
self.get_context_data(form=form, weather_forecast_form=weather_forecast_form)
)
def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
weather_forecast_form = WeatherForecastFormset(self.request.POST)
if form.is_valid() and weather_forecast_form.is_valid():
return self.form_valid(form, weather_forecast_form)
else:
return self.form_invalid(form, weather_forecast_form)
def form_valid(self, form, weather_forecast_form):
self.object = form.save(commit=False)
for weather_form in weather_forecast_form:
weather_object = weather_form.save()
self.object.weatherforecast_set.add(weather_object)
self.object.save()
form.save_m2m()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, weather_forecast_form):
return self.render_to_response(
self.get_context_data(form=form, weather_forecast_form=weather_forecast_form)
)

在尝试用它的InlineFormset提交我的表格后,我收到了这个错误:

Request Method: POST
Request URL:    http://localhost:8000/forecaster/my-clients/6/one_day/
Django Version: 1.11
Exception Type: ValueError
Exception Value:    
Unsaved model instance <OneDayForecast: Forecast for: client1> cannot be used in an ORM query.

问题可能在于form_valid方法中的commit=False,但我不知道如何修复它

有人知道解决这个问题吗?谢谢

好的,所以我认为在postform_valid()方法中都存在一些问题。我已经参考了我自己的内联表单集实现,看看你有什么不同的做法。

首先,我认为post方法的第一行应该是self.object = self.get_object()

第二,weather_forecast_form = WeatherForecastFormset(self.request.POST)应该是weather_forecast_form = WeatherForecastFormset(self.request.POST, instance=self.object)
请注意我们获得的对象和在表单集中的实例中使用它之间的关系。以上就是post方法的全部内容。

现在,在我自己的实现中,我有很多表单集,所以我如下循环遍历每个表单集(如果将表单集放入列表并将其传递给form_valid,则可以使用完全相同的代码(:

def form_valid(self, form, formsets):
self.object = form.save()
for formset in formsets:
formset.instance = self.object
formset.save()
return HttpResponseRedirect(self.get_success_url())

请注意,我们在此处完全保存父窗体,包括提交它。然后保存所有窗体集。如果你想保留你的单一表单集,你可以很容易地将上面的代码更改为以下代码:

def form_valid(self, form, weather_forecast_form):
self.object = form.save()
weather_forecast_form.instance = self.object
weather_forecast_form.save()
return HttpResponseRedirect(self.get_success_url())

您在问题底部报告的错误是form.save(commit=False)的直接结果。那里发生的事情是,你"假装"救了父母,然后试图完全救孩子。数据库没有父级的记录,所以它会抛出那个错误。在保存多对多记录之前提交是必须的(至少根据我的经验(。

相关内容

  • 没有找到相关文章

最新更新