django - 从不同的模型字段名称中获取一组对象

时间:2013-11-09 22:52:53

标签: django django-models django-views django-orm

请看看我的模特。

class BackgroundImage(models.Model):
    user = models.ForeignKey(User)
    image = models.ImageField(upload_to=get_upload_file_name)
    caption = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)

class ProfilePicture(models.Model):
    user = models.ForeignKey(User)
    image = models.ImageField(upload_to=get_upload_file_name)
    caption = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)

class Album(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)

    class Meta:
        ordering = ['-pub_date']
        verbose_name_plural = ('Albums')

    def __unicode__(self):
        return self.name

class Photo(models.Model):
    user = models.ForeignKey(User)
    album = models.ForeignKey(Album, default=3)
    image = models.ImageField(upload_to=get_upload_file_name)
    caption = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)

如何从一组Photo中获取ProfilePictureBackgroundImageimage field的所有图像。然后按-pub_date过滤它们以显示在模板中?请帮帮我。非常感谢!谢谢。

修改

N.B:我需要ProfilePictureBackgroundImageUserProfile合作:

from django.db import models
from django.contrib.auth.models import User
from profile_picture.models import ProfilePicture
from background_image.models import BackgroundImage

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    permanent_address = models.TextField()
    temporary_address = models.TextField()
    profile_pic = models.ForeignKey(ProfilePicture)
    background_pic = models.ForeignKey(BackgroundImage)

    def __unicode__(self):
        return self.user.username

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

1 个答案:

答案 0 :(得分:4)

InheritanceManager作为django-model-utils的一部分提供,允许您执行此操作,请参阅docs

要在Linux / Mac中安装:

sudo pip install django-model-utils

令人讨厌的是,在Windows上使用easy_installpip安装并不是那么简单,请参阅:How do I install Python packages on Windows?。一种快速而简单的方法是将django-model-util/目录从here下载到django项目的顶层目录中,如果您打算将整个项目复制到生产网络服务器,这将非常方便。 / p>

为了使用InheritanceManager,模型需要稍微重构:

from django.db import models
from django.contrib.auth.models import User
from datetime import datetime
from model_utils.managers import InheritanceManager

get_upload_file_name = 'images/' # I added this to debug models

class BaseImage(models.Model):
    user = models.ForeignKey(User)
    image = models.ImageField(upload_to=get_upload_file_name)
    caption = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)

    objects = InheritanceManager()

class BackgroundImage(BaseImage):
    pass

class ProfilePicture(BaseImage):
    pass

class Album(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)

    class Meta:
        ordering = ['-pub_date']
        verbose_name_plural = ('Albums')

    def __unicode__(self):
        return self.name

class Photo(BaseImage):
    album = models.ForeignKey(Album, default=3)

所有Image模型现在都继承自一个共同的超类,它创建了InheritanceManager的实例。我还将所有重复的属性都移到了超类中,但这并不是绝对必要的,使用InheritanceManager意味着仍然可以在模板中访问BaseImage中不存在的任何属性。

检索按-pubdate排序的列表:

BaseImage.objects.select_subclasses().order_by("-pub_date")

在视图中使用:

def recentImages(request):
    r = BaseImage.objects.select_subclasses().order_by("-pub_date")[:20]
    return  render_to_response("recentImages.html", { "imageList" : r })

要在模板中使用:

{% for photo in imageList %}
  <img src="{{ photo.image.url }}" />
{% endfor %}

这是你想要的吗?

修改

以下代码仍可正常使用新模型:

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    permanent_address = models.TextField()
    temporary_address = models.TextField()
    profile_pic = models.ForeignKey(ProfilePicture)
    background_pic = models.ForeignKey(BackgroundImage)

确保ForeignKey关系中最后两个模型的名称正确无误!