django - get_or_create() 未能保存到 sqlite 数据库

-1 投票
1 回答
1205 浏览
提问于 2025-04-20 22:06

我正在尝试在一个循环中保存多个对象。

for i in range(0,12):
        some_url = "blabla.com/signnum=" + str(i)
        req = urllib2.Request(astro_url,headers=hdr)
        str_response = urllib2.urlopen(req)
        json_str = json.load(str_response)
        with transaction.atomic():
            if i == 0:
                capricorn, cp_created = Capricorn.objects.get_or_create(astro_date=json_str['daily']['data_date'],
                        defaults={
                                  'headline': json_str['daily']['headline'],
                                  'headcontent':json_str['daily']['content'],
                                  'rating':json_str['daily']['rating'],
                                  'love_rate':json_str['daily']['love'],
                        })
                if cp_created:
                    print 'Capricorn saved'
                else:
                    print 'Capricorn is already in db'
            if i == 1:
                #different model
            if i == 2:
                #different model
            ....
            ....

这个过程会持续到第12个对象,字段是一样的,只是模型名称不同。

我遇到的问题是,第12个对象没有被插入到数据库中,尽管

if last_created:
     print last_createdobj.id
     print 'LastModelObject saved'
else:
     print 'LastModelObject is already in db'

打印出来的是 1LastModelObject saved,其他的对象都成功插入了。

这是怎么回事呢?循环确实执行了12次,而且写入数据库的操作是原子的。这里可能出什么问题呢?我真的卡住了……

我使用的是sqlite(开发版),它打印出的ID是 1,但在数据库中并不存在,这到底是怎么回事?

1 个回答

1

与其写12个if语句和12个不同的模型,不如考虑改变模型的结构。可以参考这样的做法

#models.py

CAPRICORN = 'Capricorn'
AQUARIUS = 'Aquarius'
PISCES = 'Pisces'
ARIES = 'Aries'
TAURUS = 'Taurus'
GEMINI = 'Gemini'
CANCER = 'Cancer'
LEO = 'Leo'
VIRGO = 'Virgo'
LIBRA = 'Libra'
SCORPIO = 'Scorpio'
SAGITTARIUS  = 'Sagittarius'

SIGN_CHOICES = (
    (1, CAPRICORN,
     2, AQUARIUS,
     3, PISCES,
     4, ARIES,
     5, TAURUS,
     6, GEMINI,
     7, CANCER,
     8, LEO,
     9, VIRGO,
     10, LIBRA,
     11, SCORPIO,
     12, SAGITTARIUS)
  )

class Sign(models.Model):
    signtype = models.CharField(choice=SIGN_CHOICES)
    astro_date = models.DateField() 
    headline = models.CharField(max_length=255)
    headcontent = models.TextField()
    rating = RatingField()    
    love_rate = models.CharField(max_length=255)

在视图中,你只需要把index+1赋值给signtype,然后get_or_create就能正常工作了。

举个例子:

astro_date = json_str['daily']['data_date']
sunsign, created = Sign.objects.get_or_create(signtype=index+1, astro_date=astro_date,
                        defaults={
                                  'headline': json_str['daily']['headline'],
                                  'headcontent':json_str['daily']['content'],
                                  'rating':json_str['daily']['rating'],
                                  'love_rate':json_str['daily']['love'],
                        })

这样一来,你的代码会更简洁,也更容易调试。

撰写回答