首页 > 解决方案 > 并非所有表单字段在保存期间都达到模型

问题描述

我正在向 django 发送一个带有裁剪尺寸的图像字段,以便在保存之前编辑图像。编辑和保存部分正在工作,但只有当我硬编码所需的尺寸时。

我的问题是,在模型中,裁剪尺寸没有出现并显示为无。

正在保存的模型使用表单集进行处理。

裁剪尺寸是后来添加的,我没有忘记迁移田地。

这是我的代码:

视图.py

for i, form in enumerate(picture_formset_from_request.forms):
    if form.is_valid():
        form.save()

从 pycharm 看来,这似乎是没有进一步传递数据的文件:

表格/模型.py

def save(self, commit=True):
    """
    Save this form's self.instance object if commit=True. Otherwise, add
    a save_m2m() method to the form which can be called after the instance
    is saved manually at a later time. Return the model instance.
    """
    if self.errors:
        raise ValueError(
            "The %s could not be %s because the data didn't validate." % (
                self.instance._meta.object_name,
                'created' if self.instance._state.adding else 'changed',
            )
        )
    if commit:
        # If committing, save the instance and the m2m data immediately.
        self.instance.save() # <- it seems to go wrong here
        self._save_m2m()
    else:
        # If not committing, add a method to the form to allow deferred
        # saving of m2m data.
        self.save_m2m = self._save_m2m
    return self.instance

save.alters_data = True

在 self.instance.save() 线上,所需的数据存在于“cleanded_data”中,但在“instance”中,x、y、w、h 都显示为 None。

x、y、w、h 是后来添加的,试图在保存之前裁剪照片。

模型.py

class LetterPicture(models.Model):
    letter = models.ForeignKey(Letter, on_delete=models.CASCADE)
    slot = models.IntegerField()
    picture = models.ImageField(upload_to="letter_pictures/%Y/%m/%d", default="empty.jpg")
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    publish = models.DateTimeField(auto_now=True)
    x = models.FloatField(null=True)
    y = models.FloatField(null=True)
    w = models.FloatField(null=True)
    h = models.FloatField(null=True)

    def save(self, *args, **kwargs):
        self.set_image( # <- data not available here
            desired_width=200,
            desired_height=200
        )

        super().save(*args, **kwargs)

表格.py

class LetterPictureModelForm(forms.ModelForm):
    picture = forms.ImageField(
        label='Picture',
        widget=ClearableFileInput(attrs={
            'class': 'form-control',
            'placeholder': 'Picture'
        })
    )
    x = forms.FloatField(widget=forms.HiddenInput())
    y = forms.FloatField(widget=forms.HiddenInput())
    w = forms.FloatField(widget=forms.HiddenInput())
    h = forms.FloatField(widget=forms.HiddenInput())

    class Meta:
        model = LetterPicture
        fields = ['picture', 'x', 'y', 'w', 'h', ]
        widgets = {
            'letter': forms.HiddenInput(),
            'slot': forms.HiddenInput(),
            'x': forms.HiddenInput(),
            'y': forms.HiddenInput(),
            'w': forms.HiddenInput(),
            'h': forms.HiddenInput(),
        }

我才 4 周进入 Django - 所以我对我到底在做什么的理解并不完全符合标准。

是什么阻止了 x、y、w、h 字段在保存期间到达模型?

标签: pythondjango

解决方案


我不完全知道问题出在哪里,但这是一个成功的解决方法,不会让人觉得太 hacky:

if form.is_valid():
    letter_picture_pre_save = form.save(commit=False)
    letter_picture_pre_save.x = form.cleaned_data['x']
    letter_picture_pre_save.y = form.cleaned_data['y']
    letter_picture_pre_save.w = form.cleaned_data['w']
    letter_picture_pre_save.h = form.cleaned_data['h']
    letter_picture_pre_save.save()

推荐阅读