我更改了.all
方法,因此它将仅选择具有published=True
的实例:
class EventManager(models.Manager):
def all(self, *args, **kwargs):
return super().get_queryset().filter(published=True, *args, **kwargs)
这与问题模型字段有关:
class Event(models.Model):
related_events = models.ManyToManyField('self', blank=True, related_name='related')
published = models.BooleanField(default=False)
objects = EventManager()
结果,ManyToManyField
最终选择了所有Event
实例。
您建议我做什么以保存published
功能并能够手动添加相关事件?谢谢。
答案 0 :(得分:1)
据我所知,Django并不使用Model.objects
作为管理器,而使用Model._basemanager
作为管理器,通常应该返回所有对象。
您可以在此处使用limit_choices_to
[Django-doc]来限制多对多字段的选择,例如:
from django.db.models import Q
class Event(models.Model):
related_events = models.ManyToManyField(
'self',
limit_choices_to=Q(published=True)
blank=False,
related_name='related'
)
published = models.BooleanField(default=False)
objects = EventManager()
您可能还希望删除blank=True
,因为这意味着默认情况下,您使该字段不显示在表单中的op。因此,如果您想手动编辑相关事件,那么blank=False
。
此外,默认情况下,ManyToManyField
至'self'
是符号。因此,这意味着如果event1
在related_events
的{{1}}中,那么event2
也在event2
的{{1}}中。如果您不想这样做,则可能要添加symmetrical=False
[Django-doc]。
请注意,在某些情况下,未发布的事件可能会在相关事件中结束。例如,通过将已发布事件添加到相关事件,然后“取消发布”它。
对于经理,我认为您最好修补related_events
方法:
event1
否则,有很多方法可以get_queryset
“ 规避”。例如:class EventManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(published=True)
仍然会给我 all filter
个字,但是由于我没有致电Event.objects.filter(id__gt=-1)
,因此不会对发布内容进行过滤。
在Event
中,您可以尝试为此.all()
指定查询集:
ModelAdmin
答案 1 :(得分:1)
这就是我最终要做的,目的是仅在html中显示已发布的事件,并在管理控制台中显示所有事件(已发布和未发布)。
class EventManager(models.Manager):
"""
changing get_queryset() to show only published events.
if all is set to True it will show both published and unpublished
if False, which is default it will show only published ones
"""
def get_queryset(self, all=False):
if not all:
return super().get_queryset().filter(published=True)
else:
return super().get_queryset()
class Event(models.Model):
related_events = models.ManyToManyField('self', blank=True, related_name='related')
published = models.BooleanField(default=False)
objects = EventManager()
然后在ModelAdmin中,我将get_queryset
设置为all
的情况下调用True
,否则我将看不到未发布的内容。
class EventAdmin(admin.ModelAdmin):
def get_queryset(self, request):
return Event.objects.get_queryset(all=True)
我不能简单地更改模型的all
方法,因为它会通过向其添加所有模型实例而与我的ManyToManyField
混在一起。所以我做了所有这一切。