我有一个基本模型/表单/ View :
模型.py
class Tag(models.Model):
name = models.CharField(max_length=100, unique=True)
表单.py
class TagForm(forms.ModelForm):
class Meta:
model = Tag
fields = '__all__'
View .py
class TagCreate(CreateView):
model = Tag
form_class = TagForm
success_url = reverse_lazy('view_somethin')
当使用 django-rest-frawework 或 Tag.objects.create(name="aagagaga") 时,“name”字段将传递到 __init__()
的Tag
,我可以做所有我想做的事情。
但是当使用基于类的 View 时,__init__()
当然被调用,但没有传递任何参数。但是,在保存方法中,我可以检查名称属性是否已设置为正确的值。
我的问题是,如果在基于类的 View 中没有任何内容传递到__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__()
中那样添加/修改属性模型的,您可以通过覆盖 form_valid
来完成CreateView
的:
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)
当然,新属性并不意味着保存在数据库中,而是可以作为有用的修饰符,就像当前用户一样。
关于python - Django CreateView 类如何实例化模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48269809/