0

我发现一些帖子或多或少与这个另一个类似的情况相同,但我无法使其中任何一个适应我的情况。如果用户尝试创建另一个与他自己已经存储在数据库中的模型同名的模型,我想要返回到我的表单并发出警告。我想使用此处描述的 Django 内置设施,但我需要一些建议来更改我的代码:你能帮帮我吗?我的代码如下:

  • 模型.py

    class ShapeFile(models.Model):
        name = models.CharField(max_length=100)
        srid = models.ForeignKey(SpatialRefSys)
        model_definition = models.OneToOneField(ModelDefinition)
        user = models.ForeignKey(User)
        color_table = models.ManyToManyField(ColorTable)
        file = models.FileField(upload_to=get_upload_path)
        class Meta:
            unique_together = ('name', 'user')
    
  • 表格.py

    class UploadForm(ModelForm):
        class Meta:
            model = ShapeFile
            fields = ('name','srid','file','color_table')
            widgets = {'srid': TextInput()}
    
  • 视图.py

    @login_required
    def index(request):
        if request.method == 'POST':
            form = UploadForm(request.POST, request.FILES)
            if form.is_valid():
                req = request.POST
                sridVal = form.cleaned_data['srid'].pk
                shpVal = form.cleaned_data['name']
    
                # The final table name is something like 'mutant_celeryPy2_123_salzburg_lc'
                end_table_name = request.user.username + "_" + shpVal + '_lc'
    
                # Creates a table, otherwise return the retrieved one
                model_def, created = ModelDefinition.objects.get_or_create(
                    app_label='celeryPy2',
                    object_name=end_table_name,
                    defaults=dict(
                       bases=(BaseDefinition(base=GeoModel),),
                       fields=(GeometryFieldDefinition(name='the_geom', srid=sridVal),
                               SmallIntegerFieldDefinition(name='cat'),)
                    )
                )
                obj = form.save(commit=False)
                obj.user = request.user
                obj.model_definition = model_def
                obj.save()
                messages.success(request, 'Shapefile upload succesful!')
                return HttpResponse('Stored!')
            else:
                print "Upload shapefile form is invalid!!!"
        else:
            form = UploadForm()
    
        return render_to_response('celeryPy2/index.html',
                                  {'form': form,},
                                  context_instance=RequestContext(request))
    

如果我以 user1 身份登录并填写表单,假设名称为“myshape”,当我提交时,我得到“已存储!” 消息:一切正常,模型 user1_myshape_lc 已创建。如果我使用相同的 user1 重新登录并尝试存储字段名称设置为“myshape”的其他数据,就像我正确得到异常之前一样:

    Exception Type: IntegrityError at /celeryPy2/main
    Exception Value: duplicate key value violates unique constraint "celeryPy2_shapefile_model_definition_id_key"
    DETAIL:  Key (model_definition_id)=(154) already exists.

如何用警告取回我的表单以获取 Django 异常错误消息?谢谢你。

4

2 回答 2

1

模型表单验证应该注意这一点并引发验证错误。但是您已经从表单中排除了该user字段,这是unique_together约束的一部分,因此它没有得到验证。参考validate_unique

您可以尝试更改视图代码以user在发布的数据中添加字段,然后实例化表单。

或者更好的方法是在表单中添加隐藏的用户字段,以便其可用request.POST并且验证按要求工作。

于 2013-04-12T11:59:05.780 回答
0

感谢 Rohan,我发现隐藏字段解决方案是最好的:现在我正确地取回我的表单并显示错误消息:Shape file with this Name and User already exists. 这是我修改后的代码以使事情正常进行:

  • 表格.py

    class UploadForm(ModelForm):
        class Meta:
            model = ShapeFile
            fields = ('name','user','srid','file','color_table')
            widgets = {'srid': TextInput(), 'user': HiddenInput()}
    
  • 视图.py

    @login_required
    def index(request):
        if request.method == 'POST':
            form = UploadForm(request.POST, request.FILES)
            if form.is_valid():
                req = request.POST
                sridVal = form.cleaned_data['srid'].pk
                shpVal = form.cleaned_data['name']
    
                # The final table name is something like 'mutant_celeryPy2_123_salzburg_lc'
                end_table_name = request.user.username + "_" + shpVal + '_lc'
    
                # Creates a table, otherwise return the retrieved one
                model_def, created = ModelDefinition.objects.get_or_create(
                    app_label='celeryPy2',
                    object_name=end_table_name,
                    defaults=dict(
                       bases=(BaseDefinition(base=GeoModel),),
                       fields=(GeometryFieldDefinition(name='the_geom', srid=sridVal),
                               SmallIntegerFieldDefinition(name='cat'),)
                    )
                )
                obj = form.save(commit=False)
                obj.model_definition = model_def
                obj.save()
                messages.success(request, 'Shapefile upload succesful!')
                return HttpResponse('Stored!')
            else:
                print "Upload shapefile form is invalid!!!"
        else:
            form = UploadForm(initial={'user': request.user})
    
        return render_to_response('celeryPy2/index.html',
                                  {'form': form,},
                                  context_instance=RequestContext(request))
    
于 2013-04-17T07:40:22.417 回答