确定M2M字段是否具有通过模型进行自定义



使用M2M关系的自定义模型,.add().create().remove()被禁用。

目前,我尝试使用.add()(或其他),并捕获并处理AttributeError以进行这些自定义M2M关系。

使用Meta API或其他方式通过模型识别自定义的"官方"方法?在我的处理中的这个阶段,我宁愿通过关系尽可能多地通过关系(而不是很多if m2m_field.related.through == FooBar语句)

(找到了Django 1.8的解决方案,但我正在开始赏金2.2)

看起来好像

m2m_field.related.through._meta.auto_created is False

做这项工作。

来自django 2.2 .add().create()等。只要您使用through_defaults:中间模型的所需字段提供相应的值,方法可以与自定义through模型一起使用。

来自文档:

您也可以使用add(),create()或set()来创建关系,只要您为任何必需的字段指定taby_defaults:

>>> beatles.members.add(john, through_defaults={'date_joined': date(1960, 8, 1)})
>>> beatles.members.create(name="George Harrison", through_defaults={'date_joined': date(1960, 8, 1)})
>>> beatles.members.set([john, paul, ringo, george], through_defaults={'date_joined': date(1960, 8, 1)})

您可能更喜欢直接创建中间模型的实例。

.remove()方法的行为需要一点关注:

如果由中间模型定义的自定义通过表不使用(model1,model2)对的唯一性,则允许多个值,remove()调用将删除所有中间模型实例:

>>> Membership.objects.create(person=ringo, group=beatles,
...     date_joined=date(1968, 9, 4),
...     invite_reason="You've been gone for a month and we miss you.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]>
>>> # This deletes both of the intermediate model instances for Ringo Starr
>>> beatles.members.remove(ringo)
>>> beatles.members.all()
<QuerySet [<Person: Paul McCartney>]>

关于_meta字段,我无法从M2M字段访问它,但是文档的上述部分似乎允许避免"体操"访问_meta
如果我发现任何有趣的东西,我会相应地更新我的答案。

django 2.2您可以直接检查通过模型是否是自动依赖的

这可以通过以下直接检查进行检查

# check for the auto_created value
m2m_field.through._meta.auto_created == False

为了测试此问题,我创建了一些带有多个M2M字段的示例拼写物,其中一个通过字段进行自定义,一个带有默认类的样本。

from django.db import models
import uuid

class Leaf(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(null=True, max_length=25, blank=True)

# Create your models here.
class MainTree(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    new_leaves = models.ManyToManyField(Leaf, through='LeafTree')
    leaves = models.ManyToManyField(Leaf, related_name='main_branch')

class LeafTree(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    tree = models.ForeignKey(MainTree, on_delete=models.CASCADE)
    leaf = models.ForeignKey(Leaf, on_delete=models.CASCADE)

测试我们的方法

In [2]: from trees.models import MainTree                                                                                                                                                                
In [3]: m = MainTree()                                                                                                                                                                                   
In [4]: m.leaves.through._meta                                                                                                                                                                           
Out[4]: <Options for MainTree_leaves>
In [5]: m.leaves.through._meta.auto_created                                                                                                                                                              
Out[5]: trees.models.MainTree
In [6]: m.new_leaves.through._meta.auto_created                                                                                                                                                          
Out[6]: False
In [7]: m.new_leaves.through._meta.auto_created == False                                                                                                                                                 
Out[7]: True
In [8]: m.leaves.through._meta.auto_created == False                                                                                                                                                     
Out[8]: False

相关内容

  • 没有找到相关文章

最新更新