问题
Please have a look at my models.
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)
How do I get all the images of Photo, ProfilePicture and BackgroundImage from their image field in one set. And then filter them by -pub_date to display in the template? Please help me out. Will be much much appreciated! Thank you.
Edit
N.B: I need ProfilePicture and BackgroundImage to work with the UserProfile like this:
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:
There is an InheritanceManager provided as part of django-model-utils which allows you to do this, see docs.
To install in Linux / Mac:
sudo pip install django-model-utils
Annoyingly, installing using easy_install or pip on windows is not quite as straight forward, see: How do I install Python packages on Windows?. A quick and dirty method is to download the django-model-util/ directory from here into the top directory of your django project, this is handy if you intend to copy the entire project across for deployment to a production webserver.
In order to use the InheritanceManager, the models need to be refactored slightly:
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)
All the Image models now inherit from a common super class which creates an instance of the InheritanceManager. I've also moved up all the duplicated attributes into the superclass, but this isn't strictly necessary, using InheritanceManager means that any attributes which are not present in BaseImage can still be accessed in the template.
To retrieve a list ordered by -pubdate:
BaseImage.objects.select_subclasses().order_by("-pub_date")
To use in a view:
def recentImages(request):
r = BaseImage.objects.select_subclasses().order_by("-pub_date")[:20]
return render_to_response("recentImages.html", { "imageList" : r })
To use in a template:
{% for photo in imageList %}
<img src="{{ photo.image.url }}" />
{% endfor %}
Is this something like what you are looking for?
Edit
The following code will still work fine, with the new models:
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)
Just make sure the names of the last two models in the ForeignKey relationship are correct!
来源:https://stackoverflow.com/questions/19884134/django-get-a-set-of-objects-from-different-models-field-names