【问题标题】:django - Get a set of objects from different models field namesdjango - 从不同的模型字段名称中获取一组对象
【发布时间】:2013-11-21 22:38:11
【问题描述】:

请看看我的模型。

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)

我如何从一组image field 中获取PhotoProfilePictureBackgroundImage 的所有图像。然后通过-pub_date过滤它们以显示在模板中?请帮帮我。将不胜感激!谢谢。

编辑

注意:我需要 ProfilePictureBackgroundImage 才能像这样使用 UserProfile

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])

【问题讨论】:

  • 创建基模型类合适吗?用userimagecaptionpub_date 字段说BaseImage(models.Model),然后创建其他模型,如BackgroundImage(BaseImage)
  • 是的,我试过这样。但我不记得为什么,由于某种原因,错误太多。我可以做for循环并从每组中获取图像列表,然后将它们添加在一起吗?

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


【解决方案1】:

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 项目的顶级目录中,如果您打算将整个项目复制到生产网络服务器上,这很方便。

为了使用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 关系中最后两个模型的名称正确!

【讨论】:

  • 非常感谢您的回答。这就是我一直在寻找的。但是还有两个问题。 django-model-utils 是否在 Windows 中工作,因为我尝试了 pip install django-model-utils 但找不到它。其次,我还能在我的UserProfile 模型中使用ProfilePictureBackgroundImage(我在编辑中添加了UserProfile 模型)吗?
  • @Aamu ProfilePicture 和 BackgroundImage 的行为将与以前完全相同。我在答案中添加了一个快速而肮脏的 windows 安装方法,如果这不起作用,还有一个替代答案。
  • 对不起。起初我做的是django-models-utils而不是django-model-utils`。现在它已安装。请您回答我的第二个问题好吗?
  • ProfilePictureBackgroundImage 的行为将与以前完全相同,它们可以在不导入 BaseImage 的情况下导入并用于其他代码段,并且诸如 ProfilePicture.objects.all().orderby("-pubdate") 之类的查询将完全正常工作像之前一样。这根本不应该影响您现有的 UserProfile 代码 - 良好重构的美感,;)。这是否回答了您的第二个问题?如果您想发布UserProfile 代码,我很乐意查看它。
  • 非常感谢您的回答和支持!!!我已将其添加到 Edit 部分。请看一下它并纠正我它是否会起作用。如果我问的问题太多,我真的很抱歉。作为一个新手,我迷失了新概念!
猜你喜欢
  • 1970-01-01
  • 2017-10-09
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多