有photologue应用程序,django的简单照片库,实现照片和图库对象。 图库对象具有ManyToMany字段,该字段引用Photo对象。Django管理,通过ManyToMany过滤对象参考
我需要能够获得给定图库的所有照片列表。是否可以添加图库过滤器照片的管理页面? 如果可能,如何做到最好?
有photologue应用程序,django的简单照片库,实现照片和图库对象。 图库对象具有ManyToMany字段,该字段引用Photo对象。Django管理,通过ManyToMany过滤对象参考
我需要能够获得给定图库的所有照片列表。是否可以添加图库过滤器照片的管理页面? 如果可能,如何做到最好?
您需要编写一个自定义FilterSpec! Custom Filter in Django Admin on Django 1.3 or below
它会是这样的:
from django.contrib.admin.filterspecs import RelatedFilterSpec, FilterSpec
from models import Gallery
class GalleryFilterSpec(RelatedFilterSpec):
def __init__(self, f, request, params, model, model_admin):
self.lookup_kwarg = f.name
self._lookup_model = f.rel.to
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.user = request.user
self.lookup_choices = [(g.pk, g.name) for g in Gallery.objects.all()]
def has_output(self):
return len(self.lookup_choices) > 1
def title(self):
return self._lookup_model._meta.verbose_name
FilterSpec.filter_specs.insert(0,
(lambda f: f.rel.to == Gallery, GalleryFilterSpec))
把它放在一个模块filters.py
在您的应用程序包,并在您导入admin.py
(它导入是非常重要的,以便过滤器变得对管理网站注册!)
编辑:“f”是字段实例,在这种情况下,models.ManyToManyField
最后一行注册了与Gallery模型有关系的所有字段的FilterSpec。如果字段是在Gallery模型中定义的,那么这将不起作用,因为django.contrib.admin.views.main.ChangeList.get_filters
会检查您在列表中定义的字段是否确实存在于模型中(对于related_name也不适用)。我认为最简单的方法是,您可以为该更改列表创建自定义模板并在其中硬编码过滤器,FilterSpec本身不需要过滤本身,django仅使用url获取参数!
好吧,我就是这么做的。
我制作了自定义管理模板“change_list.html”。自定义模板标签会创建所有现有图库的列表。过滤是这样的:
class PhotoAdmin(admin.ModelAdmin):
...
def queryset(self, request):
if request.COOKIES.has_key("gallery"):
gallery = Gallery.objects.filter(title_slug=request.COOKIES["gallery"])
if len(gallery)>0:
return gallery[0].photos.all()
return super(PhotoAdmin, self).queryset(request)
Cookie设置为javascript。
为了将来可供他人查找,如果您有关系是双向的,那么您可以通过ModelAdmin获取照片或相册的照片。
比方说,你有你的照片模型修改列表视图:
from django.contrib import admin
from yourapp.models import Photo
class PhotoAdmin(admin.ModelAdmin):
list_filter = ('galleries',)
admin.site.register(Photo, PhotoAdmin)
然后在管理你会看到一个过滤器显示所有的画廊,如果你点击一个它会过滤列表只显示该画廊的照片。
当然,如果有很多画廊,这可能是不实际的,但只需使用记录良好的ModelAdmin,而不是将模板或filterspec混合在一起即可到达那里。
http://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-objects
@Jough登普西指出,你也许并不需要一个定制的FILTERSPEC只是针对M2M领域。
但今天我发现我想要一个django-taggit标记字段。标签基本上是一个m2m关系,但如果您尝试将标记字段添加到list_filter中,它会抱怨'TaggableManager' object has no attribute 'get_choices'
。
在这种情况下,它是@ lazerscience的代码来救援......
然而,它反对的Django 1使用时没有工作。3,需要添加几条新线,比较我以下的版本:
class TagFilterSpec(RelatedFilterSpec):
def __init__(self, f, request, params, model, model_admin, field_path=None):
super(RelatedFilterSpec, self).__init__(
f, request, params, model, model_admin, field_path=field_path)
self.lookup_title = f.verbose_name # use field name
self.lookup_kwarg = f.name
self.lookup_kwarg_isnull = '%s__isnull' % (self.field_path)
self._lookup_model = f.rel.to
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.lookup_val_isnull = request.GET.get(
self.lookup_kwarg_isnull, None)
self.user = request.user
self.lookup_choices = [(g.pk, g.name) for g in Tag.objects.all()]
def has_output(self):
return len(self.lookup_choices) > 1
def title(self):
return self._lookup_model._meta.verbose_name
FilterSpec.filter_specs.insert(0,
(lambda f: f.rel.to == Tag, TagFilterSpec))
什么是代码中的“f”?它是照片实例吗? 该代码注册GalleryFilterSpec的某些照片模型领域,不是吗? 照片模型没有涉及到图库的字段。 感谢您的帮助! – 2010-06-14 12:06:20
我的回答太长,以至于无法发表评论,请参阅上面的修改! – 2010-06-14 12:31:46
那么,“f”是字段。 看起来我应该更改图库和照片模型,以便能够按照图库过滤照片。无论如何,示例很棒。再次感谢 – 2010-06-14 12:32:01