Django自定义validate_unique方法适用于在管理站点中保存新对象,但不在视图和模板中保存(`self`尚不存在)

时间:2012-04-12 22:53:25

标签: django validation django-models django-forms django-admin

我有几个类似validate_unique覆盖的模型,如this question中所示。这是在models.py:

class TeachingGroup(models.Model):
    cohort = models.ForeignKey(Cohort)
    name = models.CharField(max_length=26)
    slug = models.CharField(max_length=30, editable=False)

    class Meta:
        unique_together = ('cohort', 'name')

    def validate_unique(self, exclude = None):
        from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
        slugfodder = u'%s %s' % (self.cohort.year_group.shortname, self.name)
        self.slug = slugify(slugfodder)
        options = dict(slug = self.slug, cohort__year_group__school = self.cohort.year_group.school)
        hits = TeachingGroup.objects.exclude(pk=self.pk).filter(**options)
        if hits.exists():
            template = """The name is used for database lookups,
                and '{0}' is too similar to '{1}', as both become
                '{2}' in your web browser's address bar."""
            message = template.format(self.name, hits[0].name, self.slug)
            raise ValidationError({NON_FIELD_ERRORS: [message]})
        super(TeachingGroup, self).validate_unique(exclude=exclude)

我没有足够的声誉来评论over there,但似乎通过在最后添加super行,我不会绕过模型的Meta: unique_together验证。

为了简洁起见,我没有包含我的模型结构,但是所有上述验证在管理站点中都运行良好,都用于更改现有对象(当我设置的名称与slug足够相似时显示错误是相同的)和添加新对象。

在呈现的网页中,我在更改现有记录时收到了预期的错误消息,但奇怪的是在从表单添加新对象时没有实例(没有实例)。相反,我得到了一系列错误,最终导致:

File "models.py" in validate_unique
  125.         slugfodder = u'%s %s' % (self.cohort.year_group.shortname, self.name)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/related.py" in __get__
  301.                 raise self.field.rel.to.DoesNotExist

在pdb中:

-> slugfodder = u'%s %s' % (self.cohort.year_group.shortname, self.name)
(Pdb) self
*** DoesNotExist:

那么管理网站如何设法验证“自我”?我的验证是否需要执行save(commit = False)

之类的操作

我当然可以添加更多细节,但我认为这里有相关内容。

1 个答案:

答案 0 :(得分:0)

好的,这里没有任何信用:我有一些愚蠢的视图功能,我知道它们不是很干,而且如上所述,结果是愚蠢的。

我迄今为止标准的views.py条目:

def edit_object(request, slug=None):
    try:
        obj = MyModel.objects.get(name=slug)
        if request.method == 'POST':
            if request.POST.get('delete'):
                obj.delete()
                return redirect(list_objects)
            form = MyModelForm(request.POST, request=request, instance=obj)
            if form.is_valid():
                form.save()
                return redirect(list_objects)
        else:
            form = MyModelForm(request=request, instance=obj)
    except MyModel.DoesNotExist:
        if request.method == 'POST':
            form = MyModelForm(request.POST, request=request)
            if form.is_valid():
                form.save()
                return redirect(list_objects)
        else:
            form = MyModelForm(request=request)
    return render_to_response('edit_objects.html', locals(), context_instance=RequestContext(request))

我的新views.py

def edit_object(request, slug=None):
    if slug:
        options = dict(name = slug)
        obj = get_object_or_404(MyModel, **options)
    else:
        obj = MyModel()
    if request.method == 'POST':
        if request.POST.get('delete'):
            obj.delete()
            return redirect(list_objects)
        form = MyModelForm(request.POST, request=request, instance=obj)
        if form.is_valid():
            form.save()
            return redirect(list_objects)
    else:
        form = MyModelForm(instance=obj, request=request)
    return render_to_response('edit_objects.html', locals(), context_instance=RequestContext(request))

我还有一个问题,其中一行:

obj = MyModel()

使用validate_unique创建错误,但我越来越近了。我用过:

obj = Cohort(year_group = theschool.yeargroup_set.all()[:1].get())

非常难看,并且在没有这样的队列时抛出异常。