我发现了一些关于this one或this other one或多或少相同情况的帖子,但我无法适应我的情况。 我想要的是,如果用户尝试创建另一个与他自己已经存储在db中的名称相同的模型,则返回我的表单并发出警告。 我想使用Django内置的设施here,但我需要一些建议来改变我的代码:请问你帮我吗? 我的代码如下:
models.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')
forms.py
class UploadForm(ModelForm):
class Meta:
model = ShapeFile
fields = ('name','srid','file','color_table')
widgets = {'srid': TextInput()}
views.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异常错误消息? 谢谢。
答案 0 :(得分:1)
模型表单验证应该处理此问题并引发验证错误。但是您已从表单中排除user
字段,这是unique_together
约束的一部分,因此无法验证。参考validate_unique
您可以尝试更改视图代码,在已发布的数据中添加user
字段,然后实例化该表单。
或者更好的方法是在表单中添加隐藏的用户字段,以便在request.POST
中可用,并且验证可以根据需要运行。
答案 1 :(得分:0)
感谢Rohan,我发现隐藏的字段解决方案是最好的:现在我正确地找回了我的表单,并显示错误消息:Shape file with this Name and User already exists
。
这是我修改过的代码,可以让事情顺利进行:
<强> forms.py 强>
class UploadForm(ModelForm):
class Meta:
model = ShapeFile
fields = ('name','user','srid','file','color_table')
widgets = {'srid': TextInput(), 'user': HiddenInput()}
<强> views.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))