首页 > 解决方案 > 如何使用带有默认参数的 update_or_create

问题描述

我有模特联盟

class League(models.Model):                         
    league = models.IntegerField(primary_key=True)                                                    
    league_name = models.CharField(max_length=200)
    country_code = models.ForeignKey("Country",null=True, on_delete=models.SET_NULL)                
    season = models.ForeignKey("Season", null=True,on_delete = models.SET_NULL, to_field = "season")                                                
    season_start = models.DateField(null = True)    season_end = models.DateField(null = True)      
    league_logo = models.URLField(null = True)      league_flag = models.URLField(null = True)      
    standings = models.IntegerField(null=True)          
    is_current = models.IntegerField(null=True)

我从这个模型创建了对象。在添加这些字段之后,我需要向 League 模型添加一些额外的字段 League 对象变得如此

class League(models.Model):                         
    league = models.IntegerField(primary_key=True)                                                    
    league_name = models.CharField(max_length=200)
    country_code = models.ForeignKey("Country",null=True, on_delete=models.SET_NULL)                
    season = models.ForeignKey("Season", null=True,on_delete = models.SET_NULL, to_field = "season")                                                
    season_start = models.DateField(null = True)    season_end = models.DateField(null = True)      
    league_logo = models.URLField(null = True)      league_flag = models.URLField(null = True)      
    standings = models.IntegerField(null=True)          
    is_current = models.IntegerField(null=True)
    cover_standings = models.BooleanField(null=True)                                                   
    cover_fixtures_events = models.BooleanField(null=True)                                           
    cover_fixtures_lineups = models.BooleanField(null=True)                                         
    cover_fixtures_statistics = models.BooleanField(null=True)                                      
    cover_fixtures_players_statistics = models.BooleanField(null=True)                               
    cover_players = models.BooleanField(null=True)                                                  
    cover_topScorers = models.BooleanField(null=True)                                               
    cover_predictions = models.BooleanField(null=True)                                              
    cover_odds = models.BooleanField(null=True)     
    lastModified = models.DateTimeField(auto_now=True)

我进行了迁移并将这些字段添加到数据库模式中。现在我想添加到这些添加的字段值。我阅读了有关 update_or_create方法并尝试使用它来更新 League 模型对象

leagues_json = json.load(leagues_all)           
data_json = leagues_json["api"]["leagues"]      
for item in data_json:                              
    league_id = item["league_id"]                   
    league_name = item["name"]                      country_q =Country.objects.get(country = item["country"])                                          
    season = Season.objects.get(season = item["season"])                                            
    season_start = item["season_start"]             
    season_end = item["season_end"]                  
    league_logo = item["logo"]                      
    league_flag = item["flag"]                        
    standings = item["standings"]                   
    is_current = item["is_current"]
    coverage_standings = item["coverage"]["standings"]                                              
    coverage_fixtures_events = item["coverage"]["fixtures"]["events"]                               
    coverage_fixtures_lineups = item["coverage"]["fixtures"]["lineups"]                             
    coverage_fixtures_statistics = item["coverage"]["fixtures"]["statistics"]                       
    coverage_fixtures_plaers_statistics = item["coverage"]["fixtures"]["players_statistics"]       
   coverage_players = item["coverage"]["players"]                                                   
   coverage_topScorers = item["coverage"]["topScorers"]                                              
   coverage_predictions = item["coverage"]["predictions"]
   coverage_odds = item["coverage"]["odds"]
   b = League.objects.update_or_create(league = league_id,
   league_name = league_name,
   country_code = country_q,season = season,
   season_start = season_start,
   season_end = season_end,
   league_logo = league_logo,
   league_flag = league_flag,
   standings = standings,
   is_current = is_current,
   cover_standings = coverage_standings, 
   cover_fixtures_events = coverage_fixtures_events,
   cover_fixtures_lineups = coverage_fixtures_lineups,
   cover_fixtures_statistics= coverage_fixtures_statistics, 
   cover_fixtures_players_statistics = coverage_fixtures_players_statistics,
   cover_players= coverage_players,
   cover_topScorers = coverage_topScorers,
   cover_predictions = coverage_predictions, 
   cover_odds = coverage_odds)

当我尝试通过上述方法更新对象时出现错误

django.db.utils.IntegrityError: duplicate key value violates unique constraint "dataflow_league_pkey"
DETAIL:  Key (league)=(1) already exists.

我阅读了update_or_create方法的默认参数,但不明白如何在我的情况下使用它。谁能帮我

标签: djangodjango-models

解决方案


如果您update_or_create像这样使用,首先,您的代码将使用所有参数搜索 db 中的行。我想你想通过联赛 id 搜索联赛,它的工作原理是这样的

您可以通过任何默认方式创建字典,我只是复制您的代码

defaults = dict(
league_name=league_name,
country_code=country_q,
season=season,
season_start=season_start,
season_end=season_end,
league_logo=league_logo,
league_flag=league_flag,
standings=standings,
is_current=is_current,
cover_standings=coverage_standings,
cover_fixtures_events=coverage_fixtures_events,
cover_fixtures_lineups=coverage_fixtures_lineups,
cover_fixtures_statistics=coverage_fixtures_statistics,
cover_fixtures_players_statistics=coverage_fixtures_players_statistics,
cover_players=coverage_players,
cover_topScorers=coverage_topScorers,
cover_predictions=coverage_predictions,
cover_odds=coverage_odds)

并使用此默认值更新或创建具有特定 ID 的联赛

League.objects.update_or_create(defaults=defaults, league=league_id)

此代码将使用league_id 找到联赛,并使用您作为默认参数传递的数据对其进行更新

或者

此代码将使用该 id 和这些参数创建新联赛


推荐阅读