Mysql 有人能解释一下Django、测试服务器和Apache中的model.save()行为吗?
我有一个Django模型,其中包含一个限制为128个字符的产品字段:Mysql 有人能解释一下Django、测试服务器和Apache中的model.save()行为吗?,mysql,django,apache,model,Mysql,Django,Apache,Model,我有一个Django模型,其中包含一个限制为128个字符的产品字段: class SKU(models.Model): ... product = models.CharField(max_length=128, null=True, blank=False) ... 在应用程序中的某一点上,我读入一些用户数据,并将其制成SKU,然后保存。事实证明,有时进入product字段的数据超过了128个字符的指定大小。Apache通过WSGI为我的应用程序提供服务时,sku.s
class SKU(models.Model):
...
product = models.CharField(max_length=128, null=True, blank=False)
...
在应用程序中的某一点上,我读入一些用户数据,并将其制成SKU,然后保存。事实证明,有时进入product字段的数据超过了128个字符的指定大小。Apache通过WSGI为我的应用程序提供服务时,sku.save()命令发出以下警告:
/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/mysql/base.py:114: Warning: Data truncated for column 'product' at row 1
……但这只是一个警告。保存sku,并且产品字段的内容被截断为128个字符。但是,当我使用Django的内置测试服务器进行测试时,sku.save()命令会导致崩溃,并导致以下(缩写)堆栈跟踪:
File "/Library/WebServer/Documents/acdc_cmd/trunk/promotions/promo_parsers.py", line 467, in createKitsAndContents
theSKU.save()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/base.py", line 463, in save
self.save_base(using=using, force_insert=force_insert, force_update=force_update)
...
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 114, in execute
return self.cursor.execute(query, args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.6-intel.egg/MySQLdb/cursors.py", line 204, in execute
if not self._defer_warnings: self._warning_check()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.6-intel.egg/MySQLdb/cursors.py", line 117, in _warning_check
warn(w[-1], self.Warning, 3)
Warning: Data truncated for column 'product' at row 1
在这种情况下,sku.save()会使程序崩溃。这意味着导入操作的结果在测试服务器上和由Apache提供服务时是不同的。我有以下问题:
Wrt#3,我可以想象自省到模型的字段定义,并手动截断字符串,然后再尝试保存它;但这是一个很大的混乱。我怀疑有一个前门的方法来实现这一点,但我找不到它。确实是一个奇怪的情况。我的建议如下: 首先,你应该尽量避免这种情况。无论apache是否正确保存数据,都应该尝试删除所有警告 最好的方法是截断所有相关位置的数据。不难也不乱 首先,我建议您在表单中包含一些
javascript
代码,以便尽快向用户反馈他做错了什么。在客户端代码安全的情况下,您应该继续并添加行
product=forms.CharField(max_length=128 ...)
在sku表单中
(无论是正常的表单
还是模型表单
。我知道您说过,在模型中进行搜索会非常混乱,但这可能是一个严重的安全问题,因此值得这么做。您可以手动截断覆盖模型或表单中的保存
方法的字符串,或者如果您确实觉得偏执狂:)
这样做会简单得多:
request.POST['product']=request.POST['product'][:128]
但遗憾的是,这不起作用,因为request.POST的类型是QueryDict
,并且是不可变的,因此您无法修改它。您可以将字典复制到新字典,然后将该对象传递给表单,而不是request.POST,但我不知道还有什么会更混乱
很抱歉,我不知道为什么Django在生产/开发环境中的行为不同。我知道MySql的旧版本的行为与您描述的方式相同(如果varchar长于指定的长度,则截断,新版本禁止此操作,但您不能在数据库引擎中打开某些内部设置)
我希望这会有所帮助。祝你好运!mysql的旧版本和指定了“不截断”选项的新版本的行为都是这样的。关于生产/开发服务器,我没有答案:(两者似乎都出现了同样的问题,apache发出警告并继续,而dev server发出警告并停止。不知道它们的行为为何不同。apache是否给出了500个内部错误??没有。上面引用了所有It报告。感谢您花时间。不客气。我很想知道您是否发现了这一切:)