模型和ModelForms:需要有一个字段 "id "的值,才能使用这种多对多的关系。

问题描述 投票:0回答:1

我正在使用一个带有多对多字段的Django模型。我还使用了一个ModelForm来生成相关的表单,我的理解是,如果没有其他的重写,Django应该能够处理多对多字段保存在ModelForm中。我的理解是,只要没有覆盖其他任何东西,Django应该能够处理保存在ModelForm中的多对多字段。

对我来说,试图这样做会导致这个错误。

Internal Server Error: /cameramodel/create/
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 97, in dispatch
    return handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/edit.py", line 172, in post
    return super().post(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/edit.py", line 141, in post
    if form.is_valid():
  File "/usr/local/lib/python3.8/site-packages/django/forms/forms.py", line 185, in is_valid
    return self.is_bound and not self.errors
  File "/usr/local/lib/python3.8/site-packages/django/forms/forms.py", line 180, in errors
    self.full_clean()
  File "/usr/local/lib/python3.8/site-packages/django/forms/forms.py", line 383, in full_clean
    self._post_clean()
  File "/usr/local/lib/python3.8/site-packages/django/forms/models.py", line 403, in _post_clean
    self.instance.full_clean(exclude=exclude, validate_unique=False)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 1188, in full_clean
    self.clean()
  File "./schema/models.py", line 1439, in clean
    if self.metering_modes is True:
  File "/usr/local/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 527, in __get__
    return self.related_manager_cls(instance)
  File "/usr/local/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py", line 838, in __init__
    raise ValueError('"%r" needs to have a value for field "%s" before '
ValueError: "<CameraModel: Canon Canonflex R2000>" needs to have a value for field "id" before this many-to-many relationship can be used.

所以我查看了文档,似乎我需要覆盖 save 中的方法 ModelForm. 所以我做了这个。

class CameraModelForm(ModelForm):
    class Meta:
        model = CameraModel
        fields = '__all__'

    def save(self, commit=True):
        form = super(CameraModelForm, self).save(commit=False)
        if commit:
            form.save(commit=False)
            form.save_m2m()
        return form

但我却得到了一个不同的错误。

TypeError at /cameramodel/create/
save() got an unexpected keyword argument 'commit'
Request Method: POST
Request URL:    http://localhost:8000/cameramodel/create/
Django Version: 2.2.12
Exception Type: TypeError
Exception Value:    
save() got an unexpected keyword argument 'commit'
Exception Location: /home/jonathan/git/camerahub/schema/models.py in save, line 1397

而且 models.py:1397 实际上是一个重写的模型保存来添加一个弹头字段。

class CameraModel(models.Model):
# other stuff here
    def save(self, *args, **kwargs):
        if not self.slug:
            custom_slugify_unique = UniqueSlugify(
                unique_check=cameramodel_check, to_lower=True)
            self.slug = custom_slugify_unique("{} {} {}".format(
                self.manufacturer.name, self.model, str(self.disambiguation or '')))
        super().save(*args, **kwargs)

值得一提的是,我在其他一些模型中使用了多对多字段,而且我没有看到它们有什么问题。不过我是PythonDjango的初学者,我在这个问题上很受困,因为仅仅是按照其他无数个帖子上的建议,比如这个帖子,并没有帮助我。感谢任何人能提供任何建议或代码片段。

如果有人需要更多的背景,整个项目是开源的,这个分支可以在这里找到。https:/github.comdjjudas21camerahubtree278c_m2m_error。

python django django-forms save django-orm
1个回答
0
投票

如果你覆盖了,那么 save 方法,这意味着你想在保存表单之前进行一些检查更改。我倒是会这样做。

def save(self):
      form = super(CameraModelForm, self).save(commit=False)
      if ...: # some condition on form values
          form.save() # remove the commit here
          form.save_m2m()
      return form
© www.soinside.com 2019 - 2024. All rights reserved.