Как использовать update_or_create с аргументом по умолчанию - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть модель Лиги

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)

Я создал объекты из этой модели. После этого мне нужно было добавить некоторые дополнительные поля в модель Лиги, после добавления этих полей объект Лиги стал таким, что

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 и попытался использовать его для обновления объектов модели Лиги

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 , но не понял, как его использовать в моем случае. Может ли кто-нибудь помочь мне

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Вы можете использовать update_or_create, как это, если существует, он возвращает obj и создал false, если не существует, он возвращает obj и создал true.

 obj, created = League.objects.update_or_create(defaults=defaults, league=league_id)
0 голосов
/ 07 ноября 2019

Если вы используете update_or_create, как это, в первую очередь, ваш код будет искать строку в БД с этими всеми параметрами. Я думаю, что вы хотите искать лигу по идентификатору лиги, и она работает следующим образом

Вы создаете диктант любым способом по умолчанию, я просто копирую ваш код

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)

И используйте эти значения по умолчанию дляобновить или создать лигу с определенным идентификатором

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

Этот код найдет лигу с помощью league_id и обновит ее данными, которые вы передали в качестве параметра по умолчанию

ИЛИ

Этот кодсоздаст новую лигу с этим идентификатором и этими параметрами

...