Django 值太长,无法更改类型字符(100)--最近切换的数据库,没有';不要在db中做任何事情

Django 值太长,无法更改类型字符(100)--最近切换的数据库,没有';不要在db中做任何事情,django,postgresql,Django,Postgresql,我最近转用了postgresql,我认为一切都很好,直到我意识到当我写这篇文章时,我得到的值对于类型字符变化来说太长了(100)。现在我在谷歌上搜索,看到了一些类似的问题,但当我尝试一些解决方案时,没有一个奏效。我会解释为什么我的问题与我的观点不同。我在models.py中有此代码 class Post(models.Model): url = models.URLField(max_length=250, blank=True, null=True) slug = model

我最近转用了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)
当我看到一些推荐的解决方案时,我尝试将我的最大长度更改为100。我不知道为什么会发生这种情况,我在db中没有任何东西。我最近转用了postgresql。你能帮我解释一下为什么会发生这个错误,以及我如何修复它吗?我应该离开乌斯拉格吗

全模型

.
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


我认为你不需要帮助解决这个问题,而是需要帮助调试它。一旦问题清楚了,解决方案似乎也清楚了。回溯可能有点不清楚,因为它要处理太多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)
这些可能看起来不像文本字段,但它们中的很多都是文本字段的变体,因为如果您仔细想想,您可能不会将整个文件存储在数据库中。相反,您要做的(以及Django默认做的)是将文件存储在某个磁盘上的某个位置,然后在数据库中存储该文件的路径,以便在需要时检索它

此外,在db中以
LongText
或其他形式存储文件路径可能是一种浪费,因此我们拥有的每个
FileField
意味着我们拥有一个具有
max_长度的字段,无论我们是否指定它。因此,上述所有字段都有一个隐式的
max_length
。实际上,您可以通过阅读Django源代码来发现这一点

源示例

例如,我从未使用过
embeddevideofield
,但事实证明是这样的,这意味着如果您不指定,默认情况下它有一个
max\u length

此外,您的各种
ImageField
s只是
FileField
的子类

将来如何调试此类问题?

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

File "ebagu/main/models.py" in save
   66.       super(Post, self).save(*args, **kwargs)
所谓“设置断点”,我指的是:

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

(事实上,我对自己有强烈的偏好,但这需要Ipython,我也强烈偏好…)

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

(pdb) len(self.image.path)
使用它,我将手动评估各个字段,并查看哪一个字段有这么长的条目阻塞了保存(可能是您的
ImageField
s中的一个)

带有警告的解决方案

或者,您可以只在所有这些字段中添加一个
max_length
,但事先警告您,您很可能需要对您更改的任何有限文本字段执行数据库迁移,因为您的数据库仍将根据列的定义验证输入的长度

脚注

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

这也可能与您是否更改了这些东西的存储位置有关。您是否更改了
媒体的设置,使文件的存储路径变长了很多

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

查看数据库


快速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\u 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命令,请键入
\?

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

您有一个没有预定义长度的SlugField吗?将其设置为255,我在代码中看不到任何带有
max_length=100
的字段,因此我怀疑您没有显示所有/相关的代码。不管怎么说,问题就在下面(你可能会通过谷歌搜索发现)——当你
             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)