Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

limiting the queryset for ManyToMany MultipleSelect in Django admin

I have a model that looks like this:

class Event(models.Model):
    event_dates = ManyToManyField("EventDate")
    #...

class EventDate(models.Model):
    event_date = DateField()
    #...

However, in the django admin MultipleSelect form field that gets show for event_dates in the EventAdmin, I'd like to limit the queryset to event_dates that are not in the past.

The queryset would be something like:

event_date_queryset = EventDate.objects.filter(event_date__gte = datetime.date.today()) 

But where can I set this queryset so that only non-past dates show up in the field?

(I don't currently have a custom form for the EventAdmin but would be happy to add one.)

like image 326
B Robster Avatar asked May 21 '13 20:05

B Robster


1 Answers

You could try:

event_dates = models.ManyToManyField("EventDate", limit_choices_to={'event_date__gte': date.today()})

taken from https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to

but then only dates in the future are shown, even if some dates in the past are still associated to Event.

If you also want all the dates you previously associated to Event you could manipulate ModelForm as following

from datetime import date

from django.contrib import admin
from django import forms
from django.db.models import Q

from models import Event, EventDate

class EventAdminForm(forms.ModelForm):
    class Meta:
        model = Event

    def __init__(self, *args, **kwargs):
        super(EventAdminForm, self).__init__(*args, **kwargs)
        if 'event_dates' in self.initial:
            self.fields['event_dates'].queryset = EventDate.objects.filter(Q(pk__in=self.initial['event_dates']) | Q(event_date__gte=date.today()))
        else:
            self.fields['event_dates'].queryset = EventDate.objects.filter(event_date__gte=date.today())

class EventAdmin(admin.ModelAdmin):
    form = EventAdminForm
    filter_horizontal = ['event_dates']
like image 164
andrea.ge Avatar answered Oct 19 '22 01:10

andrea.ge