我有一個模型,根據對象是由用戶還是由系統創建,對其名稱字段使用不同的驗證。Django CreateView:在驗證前設置用戶
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 },
)
我想創建一個窗體和一個CreateView,用戶可以用它創建對象。當用戶創建這樣的對象時,用戶應該被用作「創建者」字段值的值。
目前,它看起來像這樣:
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)
我用這種方式寫它,因爲那是答案此相關的問題:
Accessing request.user in class based generic view CreateView in order to set FK field in Django
不幸的是,它不工作:視圖只允許我創建以下劃線開頭的符號,它應該做相反的操作。但是,當我創建符號時,創建者字段無論如何都會正確設置。
我認爲問題在於創建者字段只有在clean()方法已經運行之後纔會被設置。
如何在調用clean()方法之前設置創建者字段?
或者,有沒有更好的方法來做我想做的事情? 在我看來,應該有一個更有效的方法來自動化邏輯,我有兩個不同的名稱字段驗證器,其選擇取決於創建者字段。
我得到一個TypeError: 「**之後的ModelFormMetaclass對象參數必須是映射,而不是NoneType」 –
記得返回'kwargs' – Alasdair