Django Foreign Key Null 和 unique 一起,加上小写

Django Foreign Key Null and unqiue togehter , plus lowercase

我有一个类别模型,它本身有一个 Foreign 并且可以有 Null 值。

我知道当外键为 Null 时,unique together 不起作用。我还想检查它们是否重复、唯一且不区分大小写(小写、上写、组合),并且 parent 和 child 不具有相同的名称。

我在该站点上找到了一些部分解决方案,但效果不佳,并且没有涵盖我的所有情况。另一件事,我在模型上进行清理,因为我将在 Admin 中有类别,所以我无法控制任何表单或视图。

现在我在“name__iexact”上有一个错误并且不明白为什么因为“name==self.name”有效。

"NameError: name '_' is not defined"

self.pk=pk ;我检查这个是因为在更新的情况下,它会找到我编辑的当前实例并抛出 ValidationError,这是不行的。

class Category(models.Model):
    name = models.CharField(max_length=255)
    parent = models.ForeignKey('self', blank=True, null=True, verbose_name='parent category')
    description = models.TextField()

    def __str__(self):
        return self.name

    def clean(self):
        cleaned_data = super().clean()

        if not self.parent:
            exists = self.__class__.objects.filter(~Q(pk=self.pk), name__iexact=self.name).exists()
            if exists:
                raise ValidationError(_('Duplicate Category Name with No Parent'), code='duplicate_no_parent')
        if self.name.lower() == self.parent.name.lower():
            raise ValidationError(_('Category Name the same as Parent Category Name'), code='duplicate_as_parent')

        return cleaned_data

name__iexact 的错误:

Exception Type:     NameError
Exception Value:    

name '_' is not defined

File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
    response = get_response(request)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\contrib\admin\options.py", line 551, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\utils\decorators.py", line 149, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\views\decorators\cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\contrib\admin\sites.py", line 224, in inner
    return view(request, *args, **kwargs)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\contrib\admin\options.py", line 1508, in add_view
    return self.changeform_view(request, None, form_url, extra_context)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\utils\decorators.py", line 67, in _wrapper
    return bound_func(*args, **kwargs)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\utils\decorators.py", line 149, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\utils\decorators.py", line 63, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\contrib\admin\options.py", line 1408, in changeform_view
    return self._changeform_view(request, object_id, form_url, extra_context)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\contrib\admin\options.py", line 1440, in _changeform_view
    if form.is_valid():
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\forms\forms.py", line 183, in is_valid
    return self.is_bound and not self.errors
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\forms\forms.py", line 175, in errors
    self.full_clean()
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\forms\forms.py", line 386, in full_clean
    self._post_clean()
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\forms\models.py", line 408, in _post_clean
    self.instance.full_clean(exclude=exclude, validate_unique=False)
  File "D:\DevEnv\PythonEnv\Django\lib\site-packages\django\db\models\base.py", line 1234, in full_clean
    self.clean()
  File "D:\DevProj\Learn\Django\ph_work\categories\models.py", line 21, in clean
    raise ValidationError(_('Duplicate Category Name with No Parent'), code='duplicate_no_parent')
NameError: name '_' is not defined

如果您要检查相同的字符串值,我建议使用 "is" 运算符:

if self.name.lower() is self.parent.lower()

通过这种方式,您可以测试它们是否共享相同的内存地址,这很好,因为 Python 在一个内存地址存储具有相同值的字符串。

试一试,并把错误堆栈放满

exists = self.__class__.objects.exclude(pk=self.pk).filter(name__iexact=self.name).exists()