我如何根据选择将数据添加到Django模型

时间:2018-08-05 10:30:15

标签: django python-3.x

假设我有一个模型和一个视图:

class DataA(models.Model):
    created = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=60)
    TYPE = (
        ("N", "Select Type"),
        ("S", "Student"),
        ("P", "Professional"),
    )
    data_type = models.CharField(
        max_length=1,
        choices=TYPE,
        default="N",
        validators=[type_val],
    )
    student = models.CharField(max_length=60, default=None)
    professional = models.CharField(
        max_length=60, default=None
    )

class DataACreateView(CreateView):
    model = DataA
    fields = "__all__"
    template_name = "api/view.html"

    def form_valid(self, form):
        p_type = self.request.POST["data_type"]
        print(p_type)
        if p_type is "S":
            print("data is S")
            # self.request.POST['professional'] = None
        elif p_type is "P":
            print("data is P")
            # self.request.POST['student'] = None
        else:
            print("data is SOme")
            # raise ValidationError('Please select a valid value')
        return HttpResponseRedirect(reverse("create"))

我尝试过它说价值观是一成不变的,我理解这一点,但是如何解决呢?

1 个答案:

答案 0 :(得分:0)

这里有几个问题...

  • 首先:您的模型名称– DataA根本没有描述性。
  • 每次保存对象时,使用auto_now=True将更新日期;这可能不是您想要的created字段所需要的。尝试使用auto_now_add=True
  • TYPE列表应被称为TYPES(因为它是一个集合)。
  • 类型列表应包含无效的选择。我认为“选择类型”不是有效的选择。 (对于表单,您可以将选择字段的empty_label设置为“选择类型”,这可能就是您想要的。)
  • 如果希望CharFields可以为空,请添加blank=True并删除(无效的)默认值None
  • 您不能安全地使用is来比较字符串。实际上,除非您非常了解自己在做什么,否则切勿使用is。请改用==。 (is是身份比较运算符,不是相等比较运算符。)

然后解决眼前的问题。

在表单类中以表单开头的表单具有其他逻辑(例如,在clean()中),这是更加习惯的Django;这样,您可以在不使用视图的情况下测试表单,并且可以重复使用表单。

(但是,如果我猜对了您的意图,那么您实际上想要这个逻辑(当类型为P时,student字段应该为空,而S / professional则相反)放在model's clean() method中。不过,出于说明目的,我们将以表格的形式进行操作。)

像这样的事情应该可以解决问题-尽管会被警告说我已经对此进行了干式编码,所以可能存在愚蠢的错误或错别字。

class DataA(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    name = models.CharField(max_length=60)
    TYPES = (("S", "Student"), ("P", "Professional"))
    data_type = models.CharField(
        max_length=1, choices=TYPES
    )  # Having no default makes choosing a choice mandatory
    student = models.CharField(max_length=60, blank=True)
    professional = models.CharField(max_length=60, blank=True)


class DataAForm(forms.ModelForm):
    class Meta:
        model = DataA
        fields = "__all__"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.fields["data_type"].empty_label = "Select Type"

    def clean(self):
        p_type = self.cleaned_data["data_type"]
        if p_type == "S":
            self.cleaned_data["professional"] = ""
        elif p_type == "P":
            self.cleaned_data["student"] = ""
        return self.cleaned_data


class DataACreateView(CreateView):
    template_name = "api/view.html"
    success_url = reverse_lazy("create")