当前位置: 首页 > 知识库问答 >
问题:

python - 使用django的modelForm出现数据只创建数据不更新数据(form.save)怎么办?

方光华
2024-01-15

使用django的modelForm出现数据只创建数据不更新数据(form.save)

models.py,数据库有多个字段

class UserInfo(models.Model):    userid = models.AutoField(verbose_name="ID", primary_key=True)    name = models.CharField(verbose_name="用户名", max_length=16)  # varchar    password = models.CharField(verbose_name="密码", max_length=100)  # varchar    age = models.IntegerField(verbose_name="年龄")  # int    phone = models.IntegerField(verbose_name="手机号")  # int    email = models.EmailField(verbose_name="邮箱", max_length=32, null=True)  # varchar    address = models.CharField(verbose_name="地区", max_length=50, null=True)  # varchar    vipoptions = [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]    viplevel = models.IntegerField(verbose_name="vip等级", default=1, choices=vipoptions)    registerdate = models.DateTimeField(verbose_name="注册时间", auto_now_add=True)  # date    logintime = models.DateTimeField(verbose_name="登录时间", null=True)  # date    superuser = models.BooleanField(verbose_name="是否超级用户", default=False)  # boolean

views.py

class UserInfo(forms.ModelForm):    class Meta:        model = models.UserInfo        fields = ['name', 'password', 'age', 'email', 'phone']  def user_list(request):    queryset = models.UserInfo.objects.all().order_by("userid")  # asc,如果("-userid")就是desc    return render(request, 'user_list.html', {'queryset': queryset})def edit_user(request):    user_id = request.GET.get("id")  # 通过id获取当前部门对象    user_object = models.UserInfo.objects.filter(userid=user_id).first()    print(user_object)    if request.method == "GET":  # 获取默认值        # print(user_id)        # print(request.GET)        # 显示标签+默认数据展示        form = UserInfo(instance=user_object)        return render(request, 'edit_user.html', {'form': form})    #print(request.POST)    form = UserInfo(data=request.POST, instance=user_object)    print(form)    if form.is_valid():         form.save()  # 如果上面参数只传入data,这里的save是新建的意思,会导致新建一个用户,加上instance是修改数据        return redirect('/user/list')    else:        return render(request, 'edit_user.html', {'form': form})

前端修改数据的页面edit_user.html

<form method="post" action="/edit/user/"  novalidate >    {% csrf_token %}    <a>用户名:</a>{{ form.name }}<span style="color:red">{{ form.user.errors.0 }}</span>    <a>密码:</a>{{ form.password }}<span style="color:red">{{ form.password.errors.0 }}</span>    <a>年龄:</a>{{ form.age }}<span style="color:red">{{ form.age.errors.0 }}</span>    <a>邮箱:</a>{{ form.email }}<span style="color:red">{{ form.email.errors.0 }}</span>    <a>手机:</a>{{ form.phone }}<span style="color:red">{{ form.phone.errors.0 }}</span>    <input type="submit" value="提交"></form>

问题是通过编辑user_list的用户数据,每次修改只会创建新的数据,并不会通过id值更新数据,已经传入instance参数,save()都不行,通过

 if form.is_valid():        form.save()

会报错Cannot force an update in save() with no primary key.,我数据库userid设置了primarykey,但是修改用户信息的时候不需要修改这个primarykey,虽然数据库字段好多,但是修改用户信息只需要修改个别字段,但是modelform的save好像要全部字段要统一修改才可以更新?那岂不是好麻烦,如果我针对上面情况,数据库多个字段,但是管理员或者个人用户只需要修部分字段怎么做?感谢大牛解答~

共有1个答案

汤乐家
2024-01-15

这个问题的原因是你在form.save(commit=False)之后,试图强制更新tool对象,但是此时tool并没有主键值,因此Django不知道该更新哪个对象。你可以尝试将tool对象的字段设置为你希望的值,然后再调用tool.save()

这是你的代码的修改版本:

if form.is_valid():    tool = form.save(commit=False)    tool.id = user_object.id  # 假设你想保留原始的id值    tool.save()    return redirect('/user/list')else:    return render(request, 'edit_user.html', {'form': form})

这样,当你调用tool.save()时,Django会知道你想更新哪个对象。当然,这也假设了你的form.save(commit=False)会返回一个与你的数据库中的UserInfo对象具有相同字段的对象,即使某些字段的值没有改变。

另外,如果你只想更新某些字段,你可以在创建form时只指定那些字段:

form = UserInfo(instance=user_object, data=request.POST)

这样,Django将只验证你指定的字段,并且只更新那些字段的值。

注意:对于具有关联关系的模型(例如,如果你的模型包含外键或一对一关系),你可能需要使用Django的内置方法来更新这些关系,例如set_related_objects()set_field_by_type()。如果你需要更多的帮助,欢迎提问。

 类似资料:
  • 本文向大家介绍Django 根据数据模型models创建数据表的实例,包括了Django 根据数据模型models创建数据表的实例的使用技巧和注意事项,需要的朋友参考一下 如果使用默认的数据库 SQLite3,则无需配置settings.py 使用其他数据库,则需要配置settings.py,这里以Mysql为例; 在models.py中完成数据模型的创建: 并且在admin.py中完成注册: 最

  • 问题内容: 我想使用Python创建Postgres数据库。 我收到以下错误: 我正在使用psycopg2进行连接。我不明白这是什么问题。我想做的是连接到数据库(Postgres): 然后创建另一个数据库: 这是我通常要做的,我想通过创建Python脚本来实现此自动化。 问题答案: 使用psycopg2扩展名ISOLATION_LEVEL_AUTOCOMMIT: 发出命令且不需要commit()或

  • 问题内容: 这是我从Google bigquery解析的数据: 作为Python新手,我真的不知道如何解析该数据以创建一个json对象,如下所示: 任何人都可以给我一些入门的提示吗? 例 在这个单词中,是995和1600。因此也是如此。 问题答案: 如果“ Z”是您的大词典,则在“响应”上您将获得所需的结构。 响应后,您将获得以下信息: 我相信它是您所需要的。比仅使用json对响应做一个就可以了。

  • 操作步骤 1.通过 tableID 实例化一个 TableObject 对象,操作该对象即相当于操作对应的数据表 let MyTableObject = new BaaS.TableObject(tableID) 参数说明 参数 类型 必填 说明 tableID Number 是 数据表 ID 2.通过 recordID 设置指定记录 let MyRecord = MyTableObject.ge

  • {% tabs first=”SDK 1.1.0 及以上版本”, second=”SDK 1.1.0 以下版本” %} {% content “first” %} SDK 1.1.0 及以上版本 操作步骤 1.通过 tableID 实例化一个 TableObject 对象,操作该对象即相当于操作对应的数据表 let MyTableObject = new wx.BaaS.TableObject(t

  • 全部的 只是想看看用表单中提交的数据更新数据库行的最佳选项是什么。我理解Laravel更新查询生成器,但是我在如何获取表单数据,然后执行该查询方面遇到了困难。相对较新的Laravel:)这是我想出的,只是从我的PHP经验和逻辑: 我曾试图将查询放入一个函数中,然后让表单操作成为函数: 正如我所说,主要问题是试图让命名的表单对象成为更新行的对象。我有两个文本输入字段,分别命名为“body”和“not