【问题标题】:How to pass request.user to a model's clean method for a foreignkey unique_together validation?如何将 request.user 传递给模型的 clean 方法以进行外键 unique_together 验证?
【发布时间】:2015-02-06 23:11:46
【问题描述】:

我正在尝试运行验证,其中用户不能两次输入相同的 name_field 但其他用户输入相同的名称不会干扰。 我尝试使用 "unique_together = (("username","name_field"))" 但是当用户输入相同的值两次时,服务器会生成完整性错误,而不是在表单字段旁边呈现警告消息。

然后我尝试在我的模型中覆盖 clean() 方法,如果我只像这样检查“field_name”,它运行良好:

def clean(self):
    existing = self.__class__.objects.filter(
                            name_field=self.name_field).count()
    if existing > 0:
        raise ValidationError({'name_field':self.username })

但我在检查用户名值时遇到了麻烦,例如:

def clean(self):
    existing = self.__class__.objects.filter(
                            username=self.username,  ###This part crashes!!! (username not found)
                            name_field=self.name_field).count()
    if existing > 0:
        raise ValidationError({'name_field':self.username })

我猜是因为在调用 clean() 期间它不是表单中不存在的实际字段。所以我的问题是我是否对这类问题进行了正确的验证?以及如何通过或在哪里可以从模型清理方法中找到当前用户的值(以一种安全的方式,希望不会在我的表单中添加字段)?

views.py

def add_stuff(request):
    if request.user.is_authenticated():
        form = addStuff(request.POST or None)
        if request.method == 'POST':
            if form.is_valid():
                sub_form = form.save(commit=False)
                sub_form.username = request.user
                sub_form.save()
                return redirect('../somewhere_else/')

forms.py

class addStuff(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(addStuff, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
                                'name_field',
                                'type_field',
                       ButtonHolder(
                                Submit('Save', 'Save')
                                   ),
        )

    class Meta:
        model = UserStuff
        fields = ('name_field',
                  'type_field',
                 )

models.py

class UserStuff(models.Model):
    username                         = models.ForeignKey(User)
    name_field                       = models.CharField(max_length=24, blank=False,null=False)
    type_field                       = models.CharField(max_length=24, blank=True,null=True)

    def clean(self):
        existing = self.__class__.objects.filter(
                                username=self.username,  ###This part crashes!!! (username not found)
                                name_field=self.name_field).count()
        if existing > 0:
            raise ValidationError({'name_field':self.username })

    def __unicode__(self):
        return "%s For User: \"%s\" " % (self.name_field, self.username)

    class Meta:
        managed = True
        db_table = 'my_db_table'
        unique_together = (("username","name_field"))

感谢您的任何见解!

【问题讨论】:

  • 您应该准确地说明“崩溃”的含义。你得到什么错误?什么是追溯?另外,我真的不知道您为什么将这种干净的方法放在模型上,而不是表单上。

标签: django forms validation unique


【解决方案1】:

我现在从表单而不是模型运行干净的覆盖(如 Daniel 所建议的那样)。这解决了很多问题,我现在有了一个可行的概念:

models.py

class UserStuff(models.Model):
    username                         = models.ForeignKey(User)
    name_field                       = models.CharField(max_length=24, blank=False,null=False)
    type_field                       = models.CharField(max_length=24, blank=True,null=True)

    def clean(self):
        existing = self.__class__.objects.filter(
                                username=self.username,  ###This part crashes!!! (username not found)
                                name_field=self.name_field).count()
        if existing > 0:
            raise ValidationError({'name_field':self.username })

    def __unicode__(self):
        return "%s For User: \"%s\" " % (self.name_field, self.username)

    class Meta:
        managed = True
        db_table = 'my_db_table'

forms.py

class addStuff(forms.ModelForm):  
    def __init__(self, *args, **kwargs):
        super(addStuff, self).__init__(*args, **kwargs)
        initial = kwargs.pop('initial')
        self.username = initial['user']
        self.helper = FormHelper()
        self.helper.form_tag = False
        self.helper.layout = Layout(
                                'name_field',
                                'type_field',
                       ButtonHolder(
                                Submit('Save', 'Save')
                                   ),
        )
    def clean(self):
        cleaned_data = super(addStuff, self).clean()
        name_field = self.cleaned_data['name_field']
        obj = UserStuff.objects.filter(username_id=self.username.id,
                                       name_field=name_field,
                                      )
        if len(obj) > 0:
            raise ValidationError({'name_field': 
                  "This name already exists!" }  ) 
        return cleaned_data
    class Meta:
        model = UserStuff
        fields = ('name_field',
                  'type_field',
                 )

views.py

def add_stuff(request):
    if request.user.is_authenticated():
        form = addStuff(request.POST or None,
                        initial={'user':request.user})
        if request.method == 'POST':
            if form.is_valid():
                sub_form = form.save(commit=False)
                sub_form.username = request.user
                sub_form.save()
                return redirect('../somewhere_else/')

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 2014-10-07
    • 1970-01-01
    • 2011-11-20
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多