0

我有两个模型:

class Game(models.Model):
    title = models.CharField(max_length='255', blank=False, db_index=True)

class GameImage(models.Model):

    TYPES = (
        ('small_image', 'Small Image'),
        ('medium_image', 'Medium Image'),
        ('feature_image', 'Feature Image'),
        ('subfeature_image', 'Sub-feature Image'),
        ('sc1', 'Screenshot 1'),
        ('sc2', 'Screenshot 2'),
        ('sc3', 'Screenshot 3'),
    )

    game = models.ForeignKey("Game", related_name="images", editable=False)
    image = ImageField(upload_to=gameimage_storage_path, max_length=255)
    type = models.CharField(max_length=16, choices=TYPES, db_index=True)

如果我做

games = Games.objects.prefetch_related('images').all()

如果我这样做,它将附加所有“图像”相关对象:

games = Games.objects.prefetch_related('images').filter(images__type__contains='small_image').all()

它将显示具有“small_image”类型图像的游戏,但仍会加载与游戏相关的所有 GameImage 对象。

如何加载游戏列表,其中每个游戏都只有类型='small_image' 的 GameImages 相关对象(它不会加载与游戏相关的其他 GameImage 对象)?我可以通过原始 sql 做到这一点,但如何通过 Django ORM 做到这一点?请帮忙。

更新。 这是我想通过 ORM 实现的 SQL 查询:

SELECT * FROM game g LEFT JOIN gameimage i ON g.id = i.game_id AND i.type = 'small_image';
4

2 回答 2

1

加入

GameImage.objects.filter(img_type='small_image').select_related('game')

左加入游戏

from django.db.models import Q

GameImage.objects.filter(
    Q(img_type='small_image') | 
    Q(game__isnull=True)
).select_related('game')

左加入游戏图片

Game.objects.filter(
    Q(images__img_type='small_image') |
    Q(id__isnull=True)
).select_related('images')
于 2012-12-23T17:08:37.543 回答
0

所以你想要所有游戏,但想检查游戏是否有 small_image 而不加载额外的相关图像:

模型.py:

from django.core.exceptions import ObjectDoesNotExist

Class Game(models.Model):
    title = models.CharField(max_length='255', blank=False, db_index=True)

    def get_small_image(self):
        try:
            return self.images.get(type='small_image')
        except ObjectDoesNotExist:
            return None

视图.py:

games = Game.objects.all()
for game in games:
    small_image = game.get_small_image()
    if small_image:
        print small_image.image.url
    else:
        print 'there is no small image for this game'
于 2012-12-22T23:20:05.630 回答