django扩展,允许将模型的“集群”作为一个单独的单元进行处理,独立于数据库

django-modelcluster的Python项目详细描述


https://travis-ci.org/wagtail/django-modelcluster.svg?branch=master

Django ModelCluster

如果您有这样的数据模型:

classBand(models.Model):name=models.CharField(max_length=255)classBandMember(models.Model):band=models.ForeignKey('Band',related_name='members',on_delete=models.CASCADE)name=models.CharField(max_length=255)

如果您能独立于数据库构建这样的对象包,这不是很好吗:

beatles=Band(name='The Beatles')beatles.members=[BandMember(name='John Lennon'),BandMember(name='Paul McCartney'),]
遗憾的是,你不能。对象需要存在于数据库中,以使外键关系起作用:

IntegrityError:nullvalueincolumn"band_id"violatesnot-nullconstraint

但如果可以呢?在各种情况下,您可能希望使用相关对象的“集群”,而不必将它们保存在数据库中:可能希望在保存之前呈现用户刚刚提交的数据的预览。也许你需要构建一个事物树,将它们序列化并交给外部系统。也许你有一个工作流程,你的模型在一个不完整的“草稿”状态下存在一个扩展的时间,或者你需要处理多个修改,并且你不想重新设计你的数据库。

django modelcluster扩展django的外键关系以使这成为可能。它引入了一种新的关系类型parentalkey,其中相关的模型被本地存储到“parent”模型,直到显式保存父模型。到目前为止,仍然可以通过QuerySet API的子集访问相关模型:

frommodelcluster.modelsimportClusterableModelfrommodelcluster.fieldsimportParentalKeyclassBand(ClusterableModel):name=models.CharField(max_length=255)classBandMember(models.Model):band=ParentalKey('Band',related_name='members',on_delete=models.CASCADE)name=models.CharField(max_length=255)>>>beatles=Band(name='The Beatles')>>>beatles.members=[...BandMember(name='John Lennon'),...BandMember(name='Paul McCartney'),...]>>>[member.nameformemberinbeatles.members.all()]['John Lennon','Paul McCartney']>>>beatles.members.add(BandMember(name='George Harrison'))>>>beatles.members.count()3>>>beatles.save()# only now are the records written to the database

有关更多示例,请参见单元测试。

多对多关系

对于多对多关系,可以使用对应的parentalmanytomanyfield

frommodelcluster.modelsimportClusterableModelfrommodelcluster.fieldsimportParentalManyToManyFieldclassMovie(ClusterableModel):title=models.CharField(max_length=255)actors=ParentalManyToManyField('Actor',related_name='movies')classActor(models.Model):name=models.CharField(max_length=255)>>>harrison_ford=Actor.objects.create(name='Harrison Ford')>>>carrie_fisher=Actor.objects.create(name='Carrie Fisher')>>>star_wars=Movie(title='Star Wars')>>>star_wars.actors=[harrison_ford,carrie_fisher]>>>blade_runner=Movie(title='Blade Runner')>>>blade_runner.actors.add(harrison_ford)>>>star_wars.actors.count()2>>>[movie.titleformovieinharrison_ford.movies.all()]# the Movie records are not in the database yet[]>>>star_wars.save()# Star Wars now exists in the database (along with the 'actor' relations)>>>[movie.titleformovieinharrison_ford.movies.all()]['Star Wars']

注意,ParentalManyToManyField是在父模型而不是相关模型上定义的,就像标准的ManyToManyField一样。还要注意的是,在与父记录关联之前,相关对象-在上述示例中的^ {TT3}$实例必须存在于数据库中。(ParentalManyToManyField允许电影和演员之间的关系存储在内存中,而无需写入数据库,但不允许Actor记录本身。)

内省

如果您需要找出父模型中存在哪些子关系——创建模型及其所有子类的深层副本,则使用^ {TT6}$函数:

>>>frommodelcluster.modelsimportget_all_child_relations>>>get_all_child_relations(Band)[<RelatedObject:tests:bandmemberrelatedtoband>,<RelatedObject:tests:albumrelatedtoband>]

这包括在父模型的任何超类上定义的关系。

要检索父模型上定义的所有parentalmanytomanyfields的列表,请使用modelcluster.models.get_all_child_m2m_relations

>>>frommodelcluster.modelsimportget_all_child_m2m_relations>>>get_all_child_m2m_relations(Movie)[<modelcluster.fields.ParentalManyToManyField:actors>]

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java提供了大量的Quartz工作线程   来自SOAPException的java抛出超时异常   java通过REST web服务同步PostgreSQL过程调用   java Hibernate:在关联表中设置值   javaimapidlechanneladapterjavax。邮政AuthenticationFailedException:[警报]同时连接太多   JavaApacheStorm:stormkafkamonitor脚本引发异常   java将jar链接到战争   Matlab与Java的集成方法   安卓公司。谷歌。ads.AdView未能实例化java。lang.ClassNotFoundException:org。json。JSONException   “String forecastStr=mForecastAdapter.getItem(position);”行中出现java错误阳光工程   java如何将Mono中的列表属性作为流量进行操作?   java DecimalFormat类不必要地给出整数   java@IfProfileValue两个spring配置文件   java如何使用SwingWorker创建多线程?   java从扩展SwingWorker的内部类触发事件   java二叉树高度实现