【问题标题】:Django models, How to make two optional fields, but when one is filled, the other one must also be filleddjango模型,如何做两个可选字段,但是一个填的时候,另一个也要填
【发布时间】:2020-04-19 11:11:23
【问题描述】:

所以,我创建了一个具有一些属性的模型,但我想专注于这两个。

class Profile(models.Model):
    RANK_OPTIONS = (
        ('A', 'A'),
        ('B', 'B'),
    )
    related_office = models.ForeignKey('OtherModule.office', 
        related_name='office',
        on_delete=models.CASCADE
    )
    rank = models.CharField(('rank'),max_length=1, choices=RANK_OPTIONS)

基本上,我需要这两个属性是可选的,但是当属性“Rank”被填充时,属性related_office也必须被填充。 你可以有一个related_office 而不是一个等级,但是一旦你有了等级,你也需要一个相关的办公室。

我该怎么做?

【问题讨论】:

标签: django django-models


【解决方案1】:

您可以通过覆盖save 方法来强制执行此类条件:

def save(self, *args, **kwargs):
    if self.rank and not self.related_office:
        raise ValueError("related_office is required!")
    super().save(*args, **kwargs)

【讨论】:

  • 当我尝试创建一个配置文件时,它给了我一个异常,但我希望它是某种验证检查,而不是让我退出表单的大错误屏幕
  • 所以如果你希望它作为表单验证,你需要重写clean 方法并检查那里的条件;查看this
【解决方案2】:

我不会在管理员保存方法中这样做。如果它在您的管理员中,请编写一个 ModelForm 并将其传递给您的管理员类,如下所示:

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = "__all__"

    def clean(self):
        cleaned_data = super().clean()
        if cleaned_data.get("rank") and not cleaned_data.get("related_office"):
            raise ValidationError('You have to select your related office for your rank')

        return cleaned_data

并在您的管理类中引用该表单:

class ProfileAdmin(admin.ModelAdmin):
    form = ProfileForm

如果您有自定义 html 模板,请在前端或后端对其进行验证。就像上面的例子一样

【讨论】:

  • 我收到一条错误消息“配置文件没有属性cleaned_data”
  • 我还需要一个“排除”属性和一个“字段”属性来创建一个modelForm
  • 我已经编辑了我的答案。如果您不想排除任何内容,则无需添加排除。你可以输入 fields = "__all__" 这将告诉 django 包含所有字段。我忘记在clean 方法中输入super()
【解决方案3】:

您可以在您的 model.py 中覆盖 clean 方法:

def clean(self):
    if self.rank and not self.related_office:
        raise forms.ValidationError({'related_office':["related_office is required!"]})

【讨论】:

  • 我设法用这个解决方案做我想要的,但使用“forms.ValidationError”而不是 ValueError
猜你喜欢
  • 2021-10-05
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 2020-11-08
  • 2017-10-24
  • 2010-10-10
相关资源
最近更新 更多