DSG
DSG

Reputation: 49

Unable to limit choices of form field to a specific user

As the title states, I am unable to limit the choices of a form field based on a specific user. For example, in the choices for the enrolled field of the form all “riders” are selectable to all “users”, rather than just the “riders” that are “owned” by the user.

I’ve tried this question and answer that essentially asks the same question, as well as some other possible solutions that deal with m2m model fields, limit_choices_to, but have not been successful.

Any advise would be greatly appreciated.

models.py

class Event(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=200, null=True)
    description = models.TextField(max_length=255, null=True, blank=True)
    start = models.DateTimeField(null=True, blank=True)
    end = models.DateTimeField(null=True, blank=True)
    enrolled = models.ManyToManyField('riders.Rider', 
               related_name='events', blank=True)

    def __str__(self):
        return self.title

model.py (different app)

class Rider(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    birthdate = models.DateField(verbose_name=None, auto_now=False)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.last_name + ', ' +self.first_name

views.py

@login_required
def enroll(request, event_id):
    event = Event.objects.get(id=event_id)

    if request.method != 'POST':
        form = EventForm(instance=event)
    else:
        form = EventForm(instance=event, data=request.POST)
        if form.is_valid():
            enroll = form.save(commit=False)
            enroll.save()
            form.save_m2m()

        return HttpResponseRedirect(reverse('riding_schedule:view_events'))

forms.py

class EventForm(forms.ModelForm):
    class Meta:
        model = Event
        fields = ['title', 'start', 'end', 'enrolled']
        labels = {'text':''}
        widgets = {

            'enrolled': forms.CheckboxSelectMultiple()
        }

Upvotes: 1

Views: 104

Answers (1)

ruddra
ruddra

Reputation: 51938

You can try like this:

First, send the current user information to the Form when form is initiated:

@login_required
def enroll(request, event_id):
    event = Event.objects.get(id=event_id)
    if request.method != 'POST':
        form = EventForm(instance=event, user=request.user)  # <-- Here
    else:
        form = EventForm(instance=event, data=request.POST)
    # ....

Then use this information in the Form like this:

class EventForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', None)
        super(EventForm, self).__init__(*args, **kwargs)
        if user:
           self.fields['enrolled'].queryset = Rider.objects.filter(owner=user)  # overriding the queryset for enrolled here

    class Meta:
        model = Event
        fields = ['title', 'start', 'end', 'enrolled']
        labels = {'text':''}
        widgets = {

            'enrolled': forms.CheckboxSelectMultiple()
        }

Upvotes: 1

Related Questions