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

Posted

技术标签:

【中文标题】django - 从不同的模型字段名称中获取一组对象【英文标题】:django - Get a set of objects from different models field names 【发布时间】: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循环并从每组中获取图像列表,然后将它们添加在一起吗? 【参考方案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 部分。请看一下它并纠正我它是否会起作用。如果我问的问题太多,我真的很抱歉。作为一个新手,我迷失了新概念!

以上是关于django - 从不同的模型字段名称中获取一组对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从 django 的模型中获取一个字段

如何从列表中的 django 模型中获取选择字段?

Python Django 模板无法从模型函数中获取名称

Django 模型 - 在选择字段中更改选项并迁移

如何从中间件中的 Django 请求对象获取视图中使用的模型名称?

如何从用户在 django 基本模板中创建的所有帖子中获取模型字段值的总和?