鱼C论坛

 找回密码
 立即注册
查看: 2624|回复: 9

[已解决]Django models 自定义一个数据表,保存其中一值问题?

[复制链接]
发表于 2023-4-25 23:28:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 abababab 于 2023-4-25 23:33 编辑

以下是一个示例代码


models.py
from django.db import models

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    age = models.IntegerField()
    phone = models.IntegerField()

    def save(self, *args, **kwargs):
        # 在保存前更新指定一列数据
        
        super(Profile, self).save(*args, **kwargs)


view.py
def activate(request, uid):
            profile = Profile.objects.get(user_id=uid)
            profile.phone = "123456789"
            psave=profile.save()
           print(psave)


Django models 自定义一个Profile数据表,保存其中一值 phone 问题?
程序返回 None
但实际数据没有存进去的。
请教下大佬了,感谢!



最佳答案
2023-4-26 15:54:25
abababab 发表于 2023-4-26 15:50
phone = models.IntegerField(null=True, blank=True)

大佬,我发现了,是别的函数也调用了一次save, ...

很高兴您找到了问题所在。如果您想要确定是哪个函数调用了 `save()` 方法并覆盖了数据,您可以尝试在 `Profile` 模型的 `save` 方法中添加一些调试信息。这将帮助您追踪到调用 `save()` 的函数。在 `models.py` 中,可以更新 `Profile` 模型的 `save` 方法,如下所示:
import traceback

class Profile(models.Model):
    ...
    
    def save(self, *args, **kwargs):
        # 在保存前更新指定一列数据

        # 添加调试信息,显示调用 save 方法的位置
        print(f"Saving Profile for user: {self.user.username}")
        traceback.print_stack(limit=4)  # 限制输出堆栈的深度,以便于阅读
        
        super(Profile, self).save(*args, **kwargs)

使用 `traceback.print_stack()` 函数,您可以在控制台中看到调用 `save()` 方法的堆栈跟踪。这将帮助您确定是哪个函数导致了问题。在修复问题后,您可以将调试信息从 `save()` 方法中删除。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-25 23:30:54 | 显示全部楼层
根据您提供的代码,这个问题可能是因为您在 `Profile` 数据表中的 `phone` 字段设置为 `IntegerField`。然而,您在 `activate` 视图函数中将其设置为字符串 `"123456789"`。这可能导致了数据保存失败。

您需要将 `phone` 字段的值更改为整数,而不是字符串。在 `views.py` 中的 `activate` 函数中,可以将以下代码:
profile.phone = "123456789"

更改为:
profile.phone = 123456789

或者,如果要将电话号码作为字符串处理,请将 `Profile` 模型中的电话字段更改为 `CharField`:
phone = models.CharField(max_length=15)

请注意,如果您将电话号码更改为 `CharField`,需要修改电话号码的最大长度,以适应可能的格式和区域代码。在这个例子中,我设置了 `max_length=15`,但您可以根据需要进行调整。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-25 23:49:46 | 显示全部楼层
isdkz 发表于 2023-4-25 23:30
根据您提供的代码,这个问题可能是因为您在 `Profile` 数据表中的 `phone` 字段设置为 `IntegerField`。然 ...

大佬,改了,还是更新不了数据呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-25 23:52:56 | 显示全部楼层
abababab 发表于 2023-4-25 23:49
大佬,改了,还是更新不了数据呢?

我明白您的困扰。让我们一步步排查问题。首先,请确保您已经在`views.py`中正确地导入了相关的模块和对象。在`views.py`中的导入部分,添加以下内容:
from django.contrib.auth.models import User
from .models import Profile

接下来,检查您的视图函数是否在接收一个有效的 `uid`。可以在激活视图中添加一些调试输出来查看接收到的 `uid`。例如:
def activate(request, uid):
    print(f"Received UID: {uid}")
    ...

确保视图接收到有效的用户 ID。如果没有,您需要检查 URL 配置或其他可能的错误。

如果您确实收到了一个有效的用户 ID,接下来检查您是否能够从数据库中获取到相关联的 `Profile` 对象。您可以尝试在获取 `Profile` 对象之后添加一些调试输出:
profile = Profile.objects.get(user_id=uid)
print(f"Profile object: {profile}")

如果在这一步没有获取到 `Profile` 对象,这意味着没有与该用户 ID 相关联的 `Profile` 对象。您需要确保在用户注册时创建了与用户关联的 `Profile` 对象。

请尝试这些更改,查看输出并检查数据是否成功更新。如果问题仍然存在,请告诉我您的控制台输出,以便我可以为您提供进一步的帮助。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-26 00:01:05 | 显示全部楼层
isdkz 发表于 2023-4-25 23:52
我明白您的困扰。让我们一步步排查问题。首先,请确保您已经在`views.py`中正确地导入了相关的模块和对象 ...

print(f"Profile object: {profile}")
有输出的,得到username的值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-26 00:13:15 | 显示全部楼层
abababab 发表于 2023-4-26 00:01
print(f"Profile object: {profile}")
有输出的,得到username的值

既然您能够成功获取到 `Profile` 对象,那么接下来我们再次检查更新 `phone` 字段的代码部分。请确保您在保存 `Profile` 对象之前正确地设置了 `phone` 字段的值。您可以在保存 `Profile` 对象之前和之后打印 `phone` 字段的值,以便于调试。

尝试更新您的 `activate` 函数,如下所示:
def activate(request, uid):
    print(f"Received UID: {uid}")

    profile = Profile.objects.get(user_id=uid)
    print(f"Profile object: {profile}")

    print(f"Phone before update: {profile.phone}")
    profile.phone = 123456789  # 或将其设置为任何您想要的有效电话号码
    profile.save()
    print(f"Phone after update: {profile.phone}")

如果您在控制台中看到电话号码在保存 `Profile` 对象之后已更新,那么您的代码应该可以正确地更新数据。但是,如果电话号码仍未更改,您可能需要考虑检查您的数据库设置或与数据库之间的连接是否存在问题。

如果问题仍然存在,请告诉我控制台的输出,以便我可以进一步帮助您。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-26 14:22:31 | 显示全部楼层
isdkz 发表于 2023-4-26 00:13
既然您能够成功获取到 `Profile` 对象,那么接下来我们再次检查更新 `phone` 字段的代码部分。请确保您在 ...

print 可以看到更新的数据。数据库的数据没变。。。
数据库的连接不是统一用的setting里的配置么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-26 14:34:00 | 显示全部楼层
abababab 发表于 2023-4-26 14:22
print 可以看到更新的数据。数据库的数据没变。。。
数据库的连接不是统一用的setting里的配置么?

既然您在打印输出中可以看到已更新的电话号码,但数据库中的数据没有更改,这可能表明某些地方存在问题。请确保在您的项目中没有多个 `Profile` 模型,这可能导致您更新的数据被错误地保存到另一个地方。

另外,尝试在 `activate` 函数中明确地调用 `save()` 方法以更新数据库记录,而不是仅仅更改模型实例的属性。以下是一个示例:
def activate(request, uid):
    print(f"Received UID: {uid}")

    profile = Profile.objects.get(user_id=uid)
    print(f"Profile object: {profile}")

    print(f"Phone before update: {profile.phone}")
    profile.phone = 123456789  # 或将其设置为任何您想要的有效电话号码

    profile.save(update_fields=['phone'])
    print(f"Phone after update: {profile.phone}")

在这个例子中,我添加了 `update_fields` 参数,明确地告诉 Django 只更新 `phone` 字段。这应该确保您在数据库中正确地更新了数据。

确实,数据库的连接是通过项目的 `settings.py` 文件统一配置的。如果您在其他部分的项目中可以成功地与数据库进行交互,那么应该可以排除数据库连接问题。请尝试以上建议,看看问题是否得到解决。如果问题仍然存在,请告诉我,我们可以继续深入研究。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-26 15:50:38 | 显示全部楼层
isdkz 发表于 2023-4-26 14:34
既然您在打印输出中可以看到已更新的电话号码,但数据库中的数据没有更改,这可能表明某些地方存在问题。 ...

phone = models.IntegerField(null=True, blank=True)

大佬,我发现了,是别的函数也调用了一次save,把数据复盖了,现在在找不知是哪个函数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-26 15:54:25 | 显示全部楼层    本楼为最佳答案   
abababab 发表于 2023-4-26 15:50
phone = models.IntegerField(null=True, blank=True)

大佬,我发现了,是别的函数也调用了一次save, ...

很高兴您找到了问题所在。如果您想要确定是哪个函数调用了 `save()` 方法并覆盖了数据,您可以尝试在 `Profile` 模型的 `save` 方法中添加一些调试信息。这将帮助您追踪到调用 `save()` 的函数。在 `models.py` 中,可以更新 `Profile` 模型的 `save` 方法,如下所示:
import traceback

class Profile(models.Model):
    ...
    
    def save(self, *args, **kwargs):
        # 在保存前更新指定一列数据

        # 添加调试信息,显示调用 save 方法的位置
        print(f"Saving Profile for user: {self.user.username}")
        traceback.print_stack(limit=4)  # 限制输出堆栈的深度,以便于阅读
        
        super(Profile, self).save(*args, **kwargs)

使用 `traceback.print_stack()` 函数,您可以在控制台中看到调用 `save()` 方法的堆栈跟踪。这将帮助您确定是哪个函数导致了问题。在修复问题后,您可以将调试信息从 `save()` 方法中删除。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-29 09:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表