类型字符变化值太长(100)----最近切换数据库,db中没有做任何事情

win*_*xee 10 django postgresql

我最近切换到postgresql,我认为一切正常,直到我意识到当我发布时我得到的值太长了类型字符变化(100).现在我用Google搜索,看到了一些类似的问题但是当我尝试一些解决方案时,没有一个能够工作.我会解释为什么我的问题在我看来是不同的.我在models.py中有这个代码

class Post(models.Model):
    url = models.URLField(max_length=250, blank=True, null=True)

    slug = models.CharField(max_length=255, unique=True)
    objects = models.Manager()    

@property

def save(self, *args, **kwargs):
    self.slug = uuslug(self.title, instance=self, max_length=255)
    super(Post, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

当我看到一些推荐的解决方案时,我确实尝试将我的max_length更改为100.我不知道为什么会发生这种情况,我在db中没有任何内容.我最近切换到postgresql.你能帮我解释为什么会出现这个错误以及如何修复它吗?我应该离开uuslug吗?

完整的模型

.
class Category(models.Model): 

    name = models.CharField(max_length=128, unique=True)
    description = models.TextField(verbose_name=('describe'))
    author = models.ForeignKey(settings.AUTH_USER_MODEL)


    def __unicode__(self): 
        return self.name

    def get_absolute_url(self):
        return "/category/%s/" %self.name

def my_handler(sender, instance, created, **kwargs):
    action.send(instance.author, verb='following', target=Category)
post_save.connect(my_handler, sender=Category)


class Post(models.Model):
    category = models.ForeignKey(Category, verbose_name=('community'))
    pub_date = models.DateTimeField(auto_now_add = True)
    url = models.URLField(max_length=250, blank=True, null=True)
    video = EmbedVideoField(verbose_name='link',help_text="Youtube", blank=True, null=True) 

    title = models.CharField(max_length = 50)
    moderator = models.ForeignKey(User)
    views = models.IntegerField(default=0)
    slug = models.CharField(max_length=255, unique=True)
    objects = models.Manager()            # default manager
    content = RichTextUploadingField(config_name='default')
    rank_score = models.FloatField(default= 1)
    image = models.ImageField(upload_to='images',blank=True, null=True)
    thumbnail = models.ImageField(upload_to='images', blank=True, null=True)


    @property
    def domain(self):
        long_url = urlparse(self.url).netloc if self.url else "be kind to one another"
        return long_url.split('.', 1)[1] if long_url.split('.', 1)[0] == 'www' else long_url
    def save(self, *args, **kwargs):
        self.slug = uuslug(self.title, instance=self, max_length=255)
        super(Post, self).save(*args, **kwargs)
    def __unicode__(self):
        return self.title 
Run Code Online (Sandbox Code Playgroud)

这是完整的回溯

Ť

raceback:
File "env/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "env/local/lib/python2.7/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  34.             return bound_func(*args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  22.                 return view_func(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  30.                 return func.__get__(self, type(self))(*args2, **kwargs2)
File "ebagu/main/views.py" in dispatch
  191.      return super(PostCreateView, self).dispatch(request, *args, **kwargs)       
File "env/local/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
  89.         return handler(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/views/generic/edit.py" in post
  249.         return super(BaseCreateView, self).post(request, *args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/views/generic/edit.py" in post
  215.             return self.form_valid(form)
File "ebagu/main/views.py" in form_valid
  186.          self.object.save()
File "ebagu/main/models.py" in save
  66.       super(Post, self).save(*args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/db/models/base.py" in save
  734.                        force_update=force_update, update_fields=update_fields)
File "env/local/lib/python2.7/site-packages/django/db/models/base.py" in save_base
  762.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "env/local/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
  846.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "env/local/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
  885.                                using=using, raw=raw)
File "env/local/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
  127.                 return getattr(self.get_queryset(), name)(*args, **kwargs)
File "env/local/lib/python2.7/site-packages/django/db/models/query.py" in _insert
  920.         return query.get_compiler(using=using).execute_sql(return_id)
File "env/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  974.                 cursor.execute(sql, params)
File "env/local/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
  79.             return super(CursorDebugWrapper, self).execute(sql, params)
File "env/local/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)
File "env/local/lib/python2.7/site-packages/django/db/utils.py" in __exit__
  97.                 six.reraise(dj_exc_type, dj_exc_value, traceback)
File "env/local/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

Exception Type: DataError at /add_post/
Exception Value: value too long for type character varying(100)
Run Code Online (Sandbox Code Playgroud)

ere*_*wok 15

我不认为你需要帮助解决这个问题,因为你需要帮助调试它.一旦问题清楚,解决方案似乎也很清楚.Traceback可能有点不清楚,因为它经历了如此多的Django源代码,它并没有告诉你哪个字段有问题.

本期背景

首先,我们在保存Post实例时遇到了问题.那么,看看你的模型定义中的所有这些字段:

 ...
  url = models.URLField(max_length=250, blank=True, null=True)
  video = EmbedVideoField(verbose_name='link',help_text="Youtube", blank=True, null=True) 
  content = RichTextUploadingField(config_name='default')
  image = models.ImageField(upload_to='images',blank=True, null=True)
  thumbnail = models.ImageField(upload_to='images', blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)

这些可能看起来不像文本字段,但其中很多都是文本字段的变体,因为如果您考虑它,您可能不会将整个文件存储在数据库中.您将要做的事情(以及Django默认执行的操作)是将文件存储在某个磁盘上的某个位置,然后在数据库中存储该文件的路径,以便您可以在需要时检索它.

此外,将数据库中的文件路径存储为LongText或者其他任何东西都可能是浪费,所以FileField我们所拥有的每一个都意味着我们有一个字段,max_length无论我们是否指定它.因此,所有上述字段都具有隐含性max_length.您可以通过阅读Django源代码来实现这一点.

来源示例

EmbedVideoField例如,我从未使用过,但事实证明它是一个子类models.URLField,如果你没有指定,它max_length默认设置为200.

此外,你的各种ImageFields为刚刚的子类FileField,其中有一个max_length100默认.

如何在未来调试这样的问题?

现在,这并不能帮助我们知道哪些字段在这种情况下会抛出错误.为此,我可能会在代码中的某处设置一个断点,可能在这里:

File "ebagu/main/models.py" in save
   66.       super(Post, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

通过"设置断点",我的意思是:

转到上述模块中的第65行,ebagu/main/models.py输入以下内容并保存模块:import pdb; pdb.set_trace()

(我实际上对ipdb有很强的偏好,但这需要Ipython,我也非常喜欢...)

运行本地服务器,并运行产生此问题的步骤.您将最终提交表单,如果您查看启动服务器的控制台,您最终将被转储到第65行的shell中.此shell是一个pdb shell,它与普通shell有不同的规则,但是您可以Post通过查看实例本身的各个字段self,以及在该方法调用的上下文中运行Python代码来评估您即将保存的实例:

(pdb) len(self.image.path)
Run Code Online (Sandbox Code Playgroud)

使用它,我会手动评估各个字段,看看哪个有这个真正很长的条目阻塞了保存(可能是你ImageField的一个).

有警告的解决方案

或者,您可以添加一个max_length到所有这些,但预先警告您很可能需要为您更改的任何有限文本字段执行数据库迁移,因为您的数据库仍将根据列的方式验证输入的长度定义.这是一个很好的StackOverflow答案,正好看这个问题.

脚注

在切换到Postgresql之前为什么不出现这个问题?有各种各样的潜在原因,但它可能与以前的数据库设置方式与Postgresql数据库的设置方式(手动与Django迁移?)有关.

它可能还与您是否更改存储这些内容的位置有关.您是否更改了MEDIA设置,以便存储文件的路径更长?

你真正应该做的是直接查看你的数据库.打开一个psql实例并让它为您描述您的表格.它会告诉你哪些字段限制为100个字符,那些字段会给你带来问题.