Django CreateView:在验证之前设置用户 [英] Django CreateView: set user before validation
问题描述
我有一个模型,根据对象是由用户还是由系统创建的,对其名称字段使用不同的验证.
I have a model that uses different validation for its name field depending on whether the object was created by a user or by the system.
class Symbol(models.Model):
name = models.CharField(_('name'), unique=True, max_length=64)
creator = models.ForeignKey('User', null=True, on_delete=models.CASCADE)
def is_system_internal(self):
"""
whether or not this Symbol belongs to the system rather than having been created by a user
"""
return (self.creator is None)
def clean(self):
"""
ensure that the Symbol's name is valid
"""
if self.is_system_internal():
if not re.match("^_[a-zA-Z0-9\-_]+$", self.name):
raise ValidationError(
_("for system-internal symbols, the name must consist of letters, numbers, dashes (-) and underscores (_) and must begin with an underscore."),
params = { 'value' : self.name },
)
else:
if not re.match("^[a-zA-Z][a-zA-Z0-9\-_]*$", self.name):
raise ValidationError(
_("the symbol name must consist of letters, numbers, dashes (-) and underscores (_) and must begin with a letter."),
params = { 'value' : self.name },
)
我想创建一个Form和一个CreateView,用户可以使用它们创建对象.用户创建此类对象时,应将用户用作创建者"字段值的值.
I want to create a Form and a CreateView with which users can create the objects. When a user creates such an object, the user should be used as the value for the value of the 'creator' field.
当前看起来像这样:
class SymbolCreateForm(forms.ModelForm):
name = forms.CharField(max_length=Symbol._meta.get_field('name').max_length, required=True)
class Meta:
model = Symbol
fields = ('name',)
class SymbolCreateView(LoginRequiredMixin, generic.CreateView):
form_class = SymbolCreateForm
template_name = 'main/symbol_create.html'
def form_valid(self, form):
# set the creator of the instance to the currently logged in user
form.instance.creator = self.request.user
return super(SymbolCreateView, self).form_valid(form)
我这样写是因为这是有关问题的答案:
I wrote it this way because that was the answer to this related question:
不幸的是,它不起作用:视图"仅允许我创建以下划线开头的Symbol,而在此情况下应相反.但是,当我创建符号时,无论如何都正确设置了创建者字段.
Unfortunately, it doesn't work: The View only allows me to create Symbols that start with an underscore, where it should do the opposite. However, when I create a Symbol, the creator field gets set correctly anyway.
我认为问题在于创建者字段仅在clean()方法已经运行之后才设置.
I think the problem is that the creator field only gets set AFTER the clean() method has already run.
在调用clean()方法之前,如何设置创建者字段?
How do I set the creator field BEFORE the clean() method is called?
或者,是否有更好的方法来做我想做的事情? 在我看来,应该有一种更有效的方法来自动化逻辑,即我有两个不同的名称字段验证器,具体取决于创建者字段.
Alternatively, is there a better way to do what I am trying to do? It seems to me like there should be a more effective way to automate the logic that I have two different validator for the name field, the choice of which depends on the creator field.
推荐答案
您可以在get_form_kwargs
方法中设置instance.creator
.
class SymbolCreateView(LoginRequiredMixin, generic.CreateView):
form_class = SymbolCreateForm
def get_form_kwargs(self):
kwargs = super(SymbolCreateView, self).get_form_kwargs()
if kwargs['instance'] is None:
kwargs['instance'] = Symbol()
kwargs['instance'].creator = self.request.user
return kwargs
检查if kwargs['instance'] is None
意味着该代码可同时用于CreateView
和UpdateView
.
Checking if kwargs['instance'] is None
means that the code works with both CreateView
and UpdateView
.
这篇关于Django CreateView:在验证之前设置用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!