简体   繁体   English

将字段从模型复制到Django中的另一个模型的功能

[英]Function to copy fields from a model to another model in django

I want to merge 2 different models with different but overlapping fields. 我想合并具有不同但重叠字段的2个不同模型。

I try to write a function that copy the fields with its data from model A to model B. 我尝试编写一个将字段及其数据从模型A复制到模型B的函数。

def create_field():
    old = DetailItem.objects.all()
    new = CrawlItem.objects.all()

    for item in old:
        c = CrawlItem.objects.get(title=item.title, description=item.description, link=item.link, cpvcode=item.cpvcode, postalcode=item.postalcode  )
        c.save()

and i don't know whereis the mistake. 而且我不知道错误在哪里。 I want to have a model that contains the data from the old model and some new fields. 我想要一个模型,其中包含旧模型和一些新字段中的数据。

Here is my code for the two models: 这是我的两个模型的代码:

class DetailItem(Base): 

  title  = models.CharField(max_length=500)
  description = models.CharField(max_length=20000)
  link = models.URLField()
  cpvcode = models.ManyToManyField('CPVCode',related_name='cpv')
  postalcode = models.ForeignKey('PostalCode',on_delete=models.SET_NULL,null=True,blank=True,related_name='postal')

def __str__(self):
    return self.title

class CrawlItem(Base):

  guid = models.CharField( primary_key=True, max_length=500)
  title = models.CharField(max_length=500)
  link = models.URLField()
  description = models.CharField(max_length=2000)
  pubdate = models.DateTimeField()
  detail = models.ForeignKey('DetailItem',on_delete=models.SET_NULL,null=True,blank=True,related_name='crawldetail')

def __str__(self):
    return str(self.title)

This is what I want to get: 这就是我想要得到的:

class CrawlItem(Base):
  guid = ...
  title = ...
  link = ...
  cpvcodes = ...
  postalcode = ...
  pubdate = ...
  vergabestelle = ...
  vergabeart = ...
  anmeldefrist = ...
  description = ...

Any ideas how to get there are highly appreciated! 如何到达那里的任何想法都受到高度赞赏!

It's not entirely clear which objects already exist in your database, and when you consider two objects to be "equal". 目前尚不清楚数据库中已经存在哪些对象,以及何时将两个对象视为“相等”。 Assuming a CrawlItem is "equal" to a "DetailItem" when title , description and link are the same, then you can use the update_or_create function like this: titledescriptionlink相同时,假设CrawlItem与“ DetailItem”“相等”,则可以使用update_or_create函数,如下所示:

for item in old:
    CrawlItem.objects.update_or_create(
        # if matching, existing item updated, otherwise new item created
        title=item.title, description=item.description, link=item.link,
        defaults = {'cpvcode': item.cpvcode, 'postalcode': item.postalcode}
    )

Alternatively, if the two models are linked with the fk as shown in your models (and you want to remove it later on), then you don't even need to check for "equal" objects because you already have all the related ones (assuming title, description and link are already equal): 另外,如果两个模型都与模型中所示的fk链接(并且您希望以后再将其删除),那么您甚至不需要检查“相等”的对象,因为您已经拥有所有相关的对象(假设标题,说明和链接已经相等):

for item in old:
    item.crawldetail.all().update(cpvcode=item.cpvcode, postalcode=item.postalcode)

in your for statement you are just trying to select de CrawlItem with the same values as DetailItem using the get queryset method. 在for语句中,您只是尝试使用get queryset方法选择与DetailItem具有相同值的de CrawlItem。

if you want to create a CrawlItem you should use the create method (docs here -> https://docs.djangoproject.com/en/2.2/ref/models/querysets/#create ) 如果要创建CrawlItem,则应使用create方法(此处的文档-> https://docs.djangoproject.com/en/2.2/ref/models/querysets/#create

c = CrawlItem.objects.create(title=item.title, ..., postalcode=item.postalcode)

it will be created when create() is called, so, you don't need to save it afterwards, c is set to the newly created object. 它会在调用create()create() ,因此,您无需在以后保存它,因为c设置为新创建的对象。

For performance reasons you can use bulk_create() method as follows (docs here -> https://docs.djangoproject.com/en/2.2/ref/models/querysets/#bulk-create ) 出于性能原因,您可以使用如下的bulk_create()方法(此处的文档-> https://docs.djangoproject.com/en/2.2/ref/models/querysets/#bulk-create

new_crawlitems = []
for item in old:
    new_crawlitems.append(CrawlItem(title=item.title, description=item.description, link=item.link, cpvcode=item.cpvcode, postalcode=item.postalcode)
CrawlItem.objects.bulk_create(new_crawlitems)

Hope this helps and put you on the right direction. 希望这会有所帮助,并为您指明正确的方向。

G. G。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM