【问题标题】:Update many-to-many field in django with field name in variable使用变量中的字段名称更新 django 中的多对多字段
【发布时间】:2012-01-11 18:00:30
【问题描述】:

当字段名称存储在变量中时,我希望能够更新模型上的多对多字段。对于普通字段(在构造函数中使用 kwargs),甚至是外键,这相对容易,但对于多对多字段则不然。情况如下:

class Book(models.Model):
    title = models.CharField(max_length=30)
    authors = models.ManyToManyField(Author)

field_name = 'title'
new = Book(**{field_name:'My Book'}) # This sets title to mybook
new.save()
my_authors = Author.objects.filter(name='Ben') # Get some authors
field_name = 'authors' 
new.XXXXXX = my_authors # Add them

我要问的是怎么做 XXXXXX 位!像其他领域一样,它在 kwargs 中不被接受,因为您首先需要一个主键,并且在保存之前不会发生这种情况。有任何想法吗?非常感谢任何帮助!这一定是可能的 - django 管理员必须以某种方式做到这一点,但我找不到在哪里。

*编辑 - 理想情况下,我正在寻找不使用 __getattribute 或 __setattr 的解决方案 - 尽管它们确实有效,但并不理想。另外,这样做时我不能以任何方式更改模型,那是别人的代码。谢谢!

谢谢各位。 本

【问题讨论】:

    标签: django django-models django-admin many-to-many


    【解决方案1】:

    阅读您的答案,我认为这是您正在寻找的:

    relation_name = 'authors'
    new.__getattribute__(relation_name) = my_authors
    

    没有参数化关系名称django n:m doc说:

    new.authors = my_authors
    

    【讨论】:

    • 谢谢,我的意思是在我的问题中说我知道你可以用 new.__setattr__(field, my_authors) 来做到这一点 - 但我想避免使用 setattr除非绝对必要,否则使用不应真正访问的对象的底层 python 方法!谢谢。
    • 那么,这不是你的解决方案吗?您可以在模型上编写自定义方法,该方法可以访问 setattr。
    • 是的,这确实有效 - 但我试图避免使用 getattribute 或 setattribute。另外,无论如何我都无法更改模型 - 它们不是我的代码。
    • 我认为它们不是一种在不使用底层 python 方法的情况下参数化方法名称的方法。或许您可以编写一个包装器,让这些代码集中在某个时间点,以便将来重构。
    • 我担心可能是这种情况!虽然,必须有办法,因为 django-admin 在保存模型等时必须使用类似的方法。除非管理员代码也使用 setattr?我想我会更深入地研究该代码!
    【解决方案2】:

    这假设作者不是被创建,而是被添加到图书的 M2M 字段中。

    my_authors = Author.objects.filter(name='Ben') # Get some authors
    
    # This will append all authors from my_authors to the M2M field.
    for a in my_authors:
        new.authors.add(a) 
    

    这是你要找的吗?

    【讨论】:

    • 谢谢,但不——“作者”这个词存储在一个变量中,所以我不能做 new.authors.add()。此外,您可以在这种情况下执行 new.authors.add(my_authors) - 它接受一个列表!不过谢谢:)
    • 你能做这样的事情吗?我还没有测试过,但你也许可以像 switch 语句一样创建字典。 fields = {'authors': new.authors, 'title': new.title}fields[field_name].add(my_authors)
    猜你喜欢
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    • 2014-06-28
    • 2012-12-01
    • 2016-08-17
    相关资源
    最近更新 更多