django 值对于类型字符来说太长,变量为(100)----最近切换了数据库,没有在数据库中执行任何操作

vfh0ocws  于 2023-01-31  发布在  Go
关注(0)|答案(4)|浏览(133)

我最近切换到postgresql,我认为一切工作正常,直到我意识到当我做后,我得到的值太长的类型字符变化(100)。现在我谷歌它,看到一些类似的问题,但当我尝试一些解决方案,他们没有一个工作。我会解释为什么我的问题是不同的,在我看来。我有这个代码在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)

当我看到一些推荐的解决方案时,我确实尝试过将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

以下是完整的追溯
T型

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)
fkaflof6

fkaflof61#

我不认为你需要帮助来解决这个问题,就像你需要帮助来调试它一样。一旦问题清楚了,解决方案似乎也清楚了。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)

这些可能看起来不像文本字段,但它们中的很多都是文本字段的变体,因为如果你仔细想想,你可能不会在数据库中存储整个文件,而是将文件存储在某个磁盘上的某个地方,然后在数据库中存储文件的路径,这样你就可以在需要的时候检索它。
此外,在数据库中将文件路径存储为LongText或其他名称可能是一种浪费,因此我们拥有的每一个FileField都意味着我们拥有一个带有max_length的字段,无论我们是否指定它。因此,以上所有字段都有一个隐式的max_length。实际上,你可以通过阅读Django源代码找到这一点。

来源示例

例如,我从来没有使用过EmbedVideoField,但它是models.URLField的子类,这意味着如果不指定max_length,则默认将其设置为200。
此外,各种ImageField只是FileField的子类,FileField的默认值为100。

将来如何调试此类问题?

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

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

我所说的“设置断点”,意思如下:
转到上述模块ebagu/main/models.py中的第65行,输入以下内容并保存模块:import pdb; pdb.set_trace()
(实际上我自己对ipdb有强烈的偏好,但那需要Ipython,我对它也有强烈的偏好...)
运行您的本地服务器,并运行产生此问题的步骤。您将最终提交表单,如果您查看启动服务器的控制台,您最终将被转储到第65行的shell中。此shell是pdb shell,它具有与普通shell不同的规则,但您可以评估即将保存的Post示例,通过查看示例self上的各个字段,并在该方法调用的上下文中运行Python代码:

(pdb) len(self.image.path)

使用它,我将手动评估各个字段,并查看哪个字段具有阻碍保存的非常长的条目(可能是您的ImageField之一)。

带警告的解决方案

或者,您可以只向所有这些字段中添加一个max_length,但是要预先警告您,您很可能需要对您更改的任何有限文本字段执行数据库迁移,因为您的数据库仍然会根据列的定义方式验证输入的长度。Here's a good StackOverflow answer looking at exactly this problem

脚注

为什么在你切换到Postgresql之前没有出现这个问题?有很多可能的原因,但这可能与以前的数据库是如何设置的以及Postgresql数据库是如何设置的有关(手动迁移还是Django迁移?)
这也可能与你是否改变了这些东西的存储位置有关。你是否改变了你的MEDIA设置,使文件存储的路径变长了很多?
你真正应该做的是直接查看你的数据库,打开一个psql示例,让它为你描述你的表,它会告诉你哪些字段限制在100个字符以内,哪些字段给你带来了问题。

cyvaqqii

cyvaqqii2#

查一下数据库。

快速psql教程

启动postgres客户端shell,例如使用python manage.py dbshell

ebagu=>

台词

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

显示您正在尝试将模型Post保存在我假设的appmain中。如果您没有更改Post的 meta中的表,则该表应该类似于main_post
您希望使用以下命令在postgres shell中显示所有表:

\d

它将以类似的方式列出表:

List of relations
 Schema |               Name                |     Type      | Owner  
--------+-----------------------------------+---------------+--------
 public | django_migrations                 | table         | hruske
 public | django_migrations_id_seq          | sequence      | hruske
 public | django_session                    | table         | hruske

如果你想检查表django_session的细节,你可以:

\d django_session

你会得到这样的结果:

Table "public.django_session"
    Column    |           Type           | Modifiers 
--------------+--------------------------+-----------
 session_key  | character varying(40)    | not null
 session_data | text                     | not null
 expire_date  | timestamp with time zone | not null
Indexes:
    "django_session_pkey" PRIMARY KEY, btree (session_key)
    "django_session_de54fa62" btree (expire_date)
    "django_session_session_key_461cfeaa630ca218_like" btree (session_key varchar_pattern_ops)

在这里,您可以看到哪些字段定义为varchar(100)
如果要了解更多psql命令,请键入\?

nwwlzxa7

nwwlzxa73#

从以前的数据库中删除迁移文件应该可以解决您的问题。

093gszye

093gszye4#

该错误是由于数据库中已保存的数据的长度超过了给定的字符数。您可能需要查看该数据并考虑修复它,或者考虑给定的字符数是否确实是您想要的限制。
如果您正在维护模型的历史记录,则还需要删除历史记录表中的数据。

相关问题