Django CreateView 类如何实例化模型



我有一个基本的模型/表单/视图:

models.py

class Tag(models.Model):
    name = models.CharField(max_length=100, unique=True)

forms.py

class TagForm(forms.ModelForm):
    class Meta:
        model = Tag
        fields = '__all__'

views.py

class TagCreate(CreateView):
    model = Tag
    form_class = TagForm
    success_url = reverse_lazy('view_somethin')

当使用 django-rest-frawework 或 Tag.objects.create(name="aagagaga"(时,"name"字段被传递给Tag__init__(),我可以做所有我想做的黑客。

但是当使用基于类的视图时,当然会调用__init__(),但不会将参数传递给。但是,在 save 方法中,我可以检查 name 属性是否已设置为良好值。

我的问题是,如果在基于类的视图的情况下,数据如何以及在何处传输到模型实例,则没有任何东西传递给__init__()?我尝试挖掘源代码但没有成功,我怀疑某个经理之王

如果要重现该问题,以下是测试代码:

class Tag(models.Model):
    name = models.CharField(max_length=100, unique=True)
    def __str__(self):
        return f"Tag {self.name}"
    def __init__(self, *args, **kwargs):
        print(args)
        print(kwargs)
        super().__init__(*args, **kwargs)
        print(self.__dict__)
    def save(self, *args, **kwargs):
        print(self.__dict__)  # the filled attributes are here, but when were they filled ?
        super().save(*args, **kwargs)

Tag.objects.create(name="aagagaga")  # this call the __init__() with args as 
# intended but when using the html view, nothing is passed

所以我找到了一种方法,我不完全是它在内部的工作方式,但我想 Django 会动态修改模型的属性。实际上,form将模型实例的引用存储在self.instance

因此,如果您想像在模型__init__()中那样添加/修改属性,您可以通过覆盖CreateView form_valid来实现:

class TagCreate(CreateView):
    model = Tag
    form_class = TagForm
    success_url = reverse_lazy('view_somethin')
    def form_valid(self, form):
        form.instance.new_attribute = "new_thing"
        return super().form_valid(form)

然后它出现在模型中。

class Tag(models.Model):
    name = models.CharField(max_length=100, unique=True)
    def save(self, *args, **kwargs):
        print(self.__dict__)  # new_attribute appeared
        self.name += self.new_attribute
        super().save(*args, **kwargs)

当然,新属性并不意味着保存在数据库中,但可以是一个有用的修饰符,就像当前用户一样。

最新更新