Django 多对多关系不保存

2024-03-02

Update:

对于任何好奇的人,我弄清楚了它是什么、为什么以及如何解决它。 在我看来,我有:fields = ['html', 'tags', 'title', 'text', 'taken_date', 'image']我在我的模板中使用 {{ form.as_p }} 。显然,一旦从表单中发布,它真的非常不希望任何其他内容触及表单中尚未存在的表单字段。 所以我从我的视图中取出了“标签”字段,它起作用了。

感谢所有回复的人。

原始问题:

使用 Django 2.0.1 和 PostgreSQL 9.2.18

我正在编写一个简单的照片库应用程序。其中我有一个照片对象和 PhotoTag 对象。照片可以有很多标签,标签可以与很多照片相关联,因此它需要是一个ManyToManyField。

保存提交的照片后,post_save 接收器调用函数来制作缩略图(工作正常)和更新标签的函数。

照片保存得很好,update_tags 被调用很好,标签从照片中读取很好,标签保存到 PhotoTag 中很好。但是将两者绑定在一起的多对多表不会插入新行。除非代码在 update_tags 函数或 post_save 接收函数期间异常退出,否则在 update_tags 后调用thumbs。

我什至尝试使用 connection.cursor 直接写入 m2m 表,它具有相同的行为。

如果我尝试再次对 Photo 对象调用 save() ,由于 post_save 信号,我就会进入无限循环。

我对发生的事情感到困惑。有什么线索吗?

# models.py

def update_tags(instance):
    tags = get_tags(instance.image)

    # Set initial values
    pt = []
    tagid = ''
    photoid = instance.id

    # Loop through tag list and insert into PhotoTag and m2m relation
    for x in range(0, len(tags)):
        # Make sure this tag doesn't already exist
        if PhotoTag.objects.filter(tag_text=tags[x]).count() == 0:
            pt = PhotoTag.objects.create(tag_text=tags[x])
            tagid = PhotoTag.objects.latest('id').id
            instance.tags.add(pt)
        else:
            # Only working with new tags right now
            pass

    return


class Photo(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL,
                               on_delete=models.CASCADE)
    title = models.CharField(max_length=200, null=True, blank=True)
    text = models.TextField(null=True, blank=True)
    html = models.BooleanField(default=False)
    filename = models.CharField(default='', max_length=100, blank=True,
                                null=True)
    image = models.ImageField(upload_to=upload_path)
    location = models.CharField(max_length=100, blank=True, null=True)
    entry_date = models.DateTimeField(default=timezone.now)
    taken_date = models.DateTimeField(blank=True, null=True)

    tags = models.ManyToManyField(PhotoTag, blank=True)


@receiver(post_save, sender=Photo)
def thumbs(sender, instance, **kwargs):
    """
    Upon photo save, create thumbnails and then
    update PhotoTag and m2m with any Exif/XMP tags
    in the photo.
    """

    mk_thumb(instance.image, 'mid')
    mk_thumb(instance.image, 'th')
    mk_thumb(instance.image, 'sm')

    update_tags(instance)

    return

-------------
From views.py
-------------

class PhotoCreate(LoginRequiredMixin, CreateView):
    model = Photo
    template_name = 'photogallery/photo_edit.html'
    fields = ['html', 'tags', 'title', 'text', 'taken_date', 'image']

    def get_initial(self):
        self.initial = {'entry_date': timezone.now()}
        return self.initial

    def form_valid(self, form):
        form.instance.author = self.request.user

        return super(PhotoCreate, self).form_valid(form)

Update:

def save(self, mkthumb='', *args, **kwargs):
      super(Photo, self).save(*args, **kwargs)
      if mkthumb != "thumbs":
          self.mk_thumb(self.image, 'mid')
          self.mk_thumb(self.image, 'th')
          self.mk_thumb(self.image, 'sm')

          self.update_tags()

          mkthumb = "thumbs"

      return

I had a 类似问题 https://stackoverflow.com/a/53608043/2996101保存用户实例时我试图添加一个组。

为什么会发生这种情况的答案在于docs https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method更明确地(使用代码)位于这张票 https://code.djangoproject.com/ticket/30022#comment:4.

保存时ModelForm()(在管理中点击“保存”),首先保存对象的实例,然后触发其所有信号等。第三步是使用保存所有 m2m 关系ModelForm().cleaned_data. If ModelForm().cleaned_data['tags'] is None,根据您的信号创建的所有关系都将被删除。

  • 一个黑客解决方案是使用post_save信号与transaction.on_commit() https://docs.djangoproject.com/en/dev/topics/db/transactions/#django.db.transaction.on_commit它将在现有事务(包括保存所有M2M关系的过程)提交到数据库后执行相关代码。

    def on_transaction_commit(func):
        ''' Create the decorator '''
        def inner(*args, **kwargs):
            transaction.on_commit(lambda: func(*args, **kwargs))
    
        return inner
    
    
    @receiver(post_save, sender=Photo)
    @on_transaction_commit
    def tags(instance, raw, **kwargs):
        """
        Create the relevant tags after the transaction 
        of instance is committed, unless the database is 
        populated with fixtures. 
        """
        if not raw:
            update_tags(instance)
    
  • 如果您的多对多关系还没有,更健全的解决方案blank=True是使用一个m2m_changed() https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed信号,如所解释的在这篇文章中 https://stackoverflow.com/questions/23795811/django-accessing-manytomany-fields-from-post-save-signal或前面提到的ticket https://code.djangoproject.com/ticket/30022#comment:4.

  • 最棒的是,放弃信号 https://lincolnloop.com/blog/django-anti-patterns-signals/并覆盖ModelForm().clean()方法用于以下情况:ModelForm()被使用,并且还覆盖Model().save()方法如果直接保存模型。

    A ModelForm().instance.my_flag将会很有用,因此您可以检查现有的Model().my_flag in Model().save()以避免访问两次数据库。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django 多对多关系不保存 的相关文章

  • 连接到上游时 Django Gunicorn nginx(111:连接被拒绝)

    一个Django应用程序在AWS实例上运行 通过gunicorn和nginx配置 它运行良好一年多了 但是突然 我收到了502 bad gateway错误 然后我在nginx错误日志中看到了下面提到的消息 2017 05 17 16 18
  • 字符串在内部存储为单独的字符,内存中的每个字符都由其他类似的字符串共享吗?

    例如 是字符串var1 ROB 存储为 3 个内存位置 R O 和 B 每个位置都有自己的地址和变量var1指向内存位置R 那它怎么指向O和B呢 并执行其他字符串 例如 var2 BOB 指向内存中相同的 B 和 Ovar1指的是 字符串如
  • 字符串中数字的连续相加

    我是一名正在学习 python 的新程序员 并且在如何完成此任务方面遇到了困难 所以本质上我有一个从文件导入的数字字符串需要读取 并且需要将第一个数字的总和添加到第二个数字并将其转换为正确的 ascii 字符 因此 例如 如果我正在读取字符
  • 组内条件计数

    我想在之后进行条件计数groupby 例如 按列的值分组A 然后计算每组中值出现的频率5出现在列中B 如果我整个过程都这样做DataFrame 只是len df df B 5 所以我希望我能做到df groupby A df B 5 siz
  • 需要Python字长函数示例

    我的家庭作业有点困难 我本来应该编写一个函数 limitWords 将输入限制为 20 个单词 如果输入超过 20 个单词 则将输入截断为仅 20 个单词 我使用 len text split 作为计算单词的方法 因此 20 个或更少的部分
  • [matplotlib]:理解“set_ydata”方法

    我试图了解如何使用 set ydata 方法 我在 matplotlib 网页上找到了很多示例 但我只找到了 set ydata 被 淹没 在大型且难以理解的代码中的代码 我想要一个简短且易于理解的代码来帮助我理解 set ydata 的工
  • 张量流 - 向量中的前 k 个值到二进制向量

    假设我有一个带有值的向量 0 4 1 2 8 7 0 2 如何获得前 k 个值的二进制向量 k 3 0 1 0 0 1 1 0 0 in 张量流 TensorFlow 的tf math top k https www tensorflow
  • 在 Windows 上使用 pycrypto 时如何修复“ImportError:无法从 Crypto.Cipher 导入名称 _AES”?

    我在 Crypto 的 Cipher 模块中有 AES Python27 Lib Crypto Cipher AES 当我尝试做的时候 from Crypto Cipher import AES 我收到以下错误 Traceback most
  • Django 模板:输出带有所有小数位的浮点数

    我如何在 django 模板中输出这个数字 小数位数是可变的 我事先不知道 x 0 000015 1 x 输出是 1 5e 05 2 x stringformat f 输出是 0 000015 这不是本地化的 应该有逗号 我需要对输出进行本
  • Django Rest框架Json解析

    我想解析传入的POSTdjangoviews py 文件中的数据 发布数据 number 17386372 data banana apple grapes 这是我尝试读取上述传入数据的方法request views py class Fr
  • 如何重写一个列表列表,使值的“孤岛”彼此唯一?

    假设我有一个列表列表 或更概念上准确的二维数组 list 1 1 0 0 0 1 1 2 0 0 0 2 2 2 0 0 0 0 2 0 0 0 0 1 0 我想识别具有相同值的不同区域并重写列表 以便每个区域都有唯一的值 如下所示 lis
  • 禁用或限制 /o/applications(django rest 框架、oauth2)

    我目前正在使用 Django Rest 框架编写 REST API 并使用 oauth2 进行身份验证 使用 django oauth toolkit 我对他们俩都很满意 他们做的正是我想要的 然而 我有一个担忧 我正在将我的应用程序传递到
  • df.style.apply 在显示中居中显示多索引值

    当我跑步时 import pandas as pd from IPython display import display df pd DataFrame a index pd MultiIndex from product 0 1 3 c
  • max()、分组依据和排序依据

    我有以下 SQL 语句 SELECT t client id max t points AS max FROM sessions GROUP BY t client id 它只是列出了客户 ID 以及他们所获得的最大积分 现在我想按 max
  • 使用 PostgreSQL 的模式和 Rails 创建多租户应用程序

    我已经想通的事情 我正在学习如何在 Rails 中创建多租户应用程序 该应用程序根据用于查看应用程序的域或子域来提供来自不同模式的数据 我已经回答了一些问题 如何让 subdomain fu 也能与域一起使用 这是有人问了同样的问题 htt
  • Django Admin Media 前缀 URL 问题

    我有以下文件夹结构 src BAT templates admin base html src BAT media base css src BAT media admin media base css 设置 py MEDIA ROOT o
  • 仅将唯一行插入 SQLite (python)

    我在用着cursor executemany将 CSV 文件中的批量行插入到 SQLite 表中 根据主键字段 其中一些行预计会重复 当我执行该命令时 可以预见的是 我会收到完整性错误 并且不会插入任何内容 如何有选择地仅插入非重复行 而无
  • 带有远程解释器的 Python 控制台无法在 PyCharm 中接受输入

    我是使用 PyCharm 进行远程开发的新手 我设置了一个远程环境 除了一个例外之外它工作正常 无法在控制台中接受用户输入 在控制台中运行以下语句时 控制台被阻塞 提示 上一个命令仍在运行 请等待或按控制台中的 Control C 来中断
  • 子进程调用,它们是并行完成的吗?

    我一直在谷歌搜索这个问题的答案 但似乎没有一个答案 谁能告诉我如果subprocess模块是否并行调用 Python 文档建议它可用于生成新进程 但没有提及它们是否并行 如果它们可以并行完成 您能否给我举一个例子或将我链接到一个例子 这取决
  • gis计算点和多边形/边界之间的距离

    我想使用 python 计算一个点到一个国家边界之间的距离shapely 它应该工作得很好 point distance poly 例如在这里展示查找多边形形状上最近点的坐标 https stackoverflow com question

随机推荐

  • Angular-cli 8 - 是否可以仅在 es2015 上构建?

    在 angular cli 版本 8 中 构建完成了 2 次 一个在 es5 中 一个在 es2015 中 是否可以只在es2015上构建 将目标更改为es5 仅在es5中完成 但我还没有找到仅在es2015中执行此操作的方法 如果您更新您
  • Android 中 onDestroy() 的使用

    如果Java提供了垃圾收集 那么Activity生命周期中还需要onDestroy 吗 onDestroy 您的 Activity 被销毁之前收到的最后一个调用 发生这种情况的原因可能是活动即将完成 有人对其调用 finish 也可能是因为
  • Tensorflow Bow 编码器说明

    有人可以向我解释一下 Tensorflow BoW 编码器正在做什么 返回什么吗 我希望获得每个文档的字数向量 就像在 sklearn 中一样 但是 显然它正在做一些更奇特的事情 在这个例子中 https github com tensor
  • MongoDB Scala - 查询文档中的特定字段值

    所以我知道在 Mongo Shell 中 您可以使用点表示法来获取任何文档中所需的字段 MongoDB Scala 中的点表示法是如何实现的 我对它是如何工作的感到困惑 以下是从集合中获取文档的代码 val record collectio
  • Chrome 扩展本机消息同步

    我在 Windows 上的本机消息同步有问题 我正在尝试同步backgroundPage 和hostApp 之间的消息 通常 我们使用这样的原生消息传递 popup js function appendMessage text docume
  • 由于 SYS_OP_C2C 内部转换,Oracle SQL 执行计划发生变化

    我想知道为什么这个查询的成本 select from address a left join name n on n adress id a id where a street 01 高于 select from address a lef
  • LongListSelector:项目点击?

    我在 Windows Phone 8 上使用 LongListSelector 控件 但无法找出处理项目点击的最佳方法 我发现的几个示例依赖于 SelectionChanged 事件 但是 这个解决方案有问题 因为如果我点击一个打开新页面的
  • 使用 cx_freeze 和 pandas 在 dateutil/zoneinfo 上出现错误 3

    当我尝试使用 cx freeze 编译 hello py 文件时 pandas 0 15 2 出现以下错误 但 0 15 1 没有错误 有人知道如何纠正它吗 我已使用 include files 函数包含 dateutil zoneinfo
  • SVN 是否允许 svn auth 文件规则的路径中存在空白?

    目前 我们遇到了包含空白且属于 svn auth 文件中的规则一部分的目录的问题 因此 我们希望拥有基于路径的授权 并拥有一个包含以下内容的文件 rw junk of me me rw 当我清除身份验证数据并签出存储库的根目录时me 我看到
  • 使用 PHPUnit 测试数组是否包含值

    我创建了这个对象数组 ad 1 new AdUnit array id gt 1 name gt Ad 1 description gt great ad code gt alpha widget id gt 123 ad 2 new Ad
  • 如何计算 Neo4j 中的排名

    我有两种类型的节点 游戏玩家 和一种关系 已玩 PLAYED关系就是拥有一个属性 点 样本数据 玩家 309274 获得10分玩家 309275 获得20分玩家 309276 获得30分玩家 309277 获得40分玩家 309278 获得
  • 使用 long double 或仅使用 double 来计算 pi?

    我正在使用冗长的公式计算 pi 我试图更熟悉浮点数等 我有一个使用双精度数的工作程序 我的代码的问题是 如果我使用双精度数 则 pi 只能精确到小数点后第七位 我无法得到更准确的信息 如果我使用 long double 则 pi 精确到小数
  • 使用 System Groovy 脚本从 Jenkins 工作区读取文件

    我有一个与此非常相似的问题 使用 Groovy 脚本从 Jenkins 中的工作区读取文件 https stackoverflow com questions 22917491 reading file from workspace in
  • NumPy 广播:计算两个数组之间的平方差之和

    我有以下代码 在 Python 中这需要很长时间 必须有一种方法可以将此计算转换为广播 def euclidean square a b squares np zeros a shape 0 b shape 0 for i in range
  • 从oracle中选择记录

    为了选择最后一条记录 当我的数据库是 MySQL 时 我使用了这个 result mysql query SELECT Id FROM test ORDER BY LENGTH Id Id ASC count mysql numrows r
  • 如果存在则推送到 JavaScript 数组,如果不存在则先创建它

    有没有办法让这条线始终工作而不抛出TypeError Cannot read property Whatever of undefined var MyArray MyArray StringVariableName StringVaria
  • 如何使用 HTML Agility Pack 清理格式不良的 HTML

    我正在尝试替换这个可怕的正则表达式集合 该集合当前用于清理格式不良的 HTML 块 并偶然发现了 C 的 HTML Agility Pack 它看起来非常强大 但是 我找不到如何使用该包的示例 在我看来 这将是其中包含的所需功能 我确信我是
  • Orchard CMS:Javascript 文件返回 404 未找到,即使它存在

    我的 Orchard 模块中的编辑器模板的 Razor 视图中有以下内容 Script Include assets js AtFoot 当页面呈现时 我可以在底部看到这一行 美丽的 唯一的问题是 当我访问该路径时 出现 404 错误 该脚
  • Angular Material Design 中的事件日历

    我想使用 Angular Material Design 默认日期选择器日历作为事件日历 喜欢 http prntscr com fpg1lw http prntscr com fpg1lw 如何在日历中列出我的活动 我只想强调 Angul
  • Django 多对多关系不保存

    Update 对于任何好奇的人 我弄清楚了它是什么 为什么以及如何解决它 在我看来 我有 fields html tags title text taken date image 我在我的模板中使用 form as p 显然 一旦从表单中发