Nothing here
Nothing here

Reputation: 2393

How to populate initial values of form from queryset

I have a FormView with a get_initial method which I am trying to use to populate the form. I am trying to get the EmployeeTypes of the receiver of the memo as values in the form.

    def get_initial(self):
        initial = super(NotificationView, self).get_initial()
        users = Memo.objects.filter(id=self.kwargs['pk']).values('receiver__employee_type')
        initial['receiving_groups'] = users
        return initial

There are 2 issues here..

  1. This returns a Queryset which looks like: <QuerySet [{'receiver__employee_type': 'Bartender'}, {'receiver__employee_type': 'Supervisor'}]> when I really need the fields in the form to be the EmployeeType itself.
  2. Most importantly - the form isn't even rendering these fields.

Here is the form just in case:

class MemoNotificationForm(forms.Form):
    class Meta:
        fields = [
            'receiving_groups'
        ]
    receiving_groups = forms.MultipleChoiceField(
        required=False,
        widget=forms.CheckboxSelectMultiple)

How do I populate the fields of the form?

EDIT:

class Memo(models.Model):
    receiver = models.ManyToManyField(EmployeeType, related_name='memos_receiver')

class EmployeeType(models.Model):
    """Stores user employee type."""
    employee_type = models.CharField(
        max_length=32,
        unique=True)

Upvotes: 1

Views: 1343

Answers (2)

Nothing here
Nothing here

Reputation: 2393

While @lain Shelvington is correct in the process he used to produce the form results, I had to do a little editing to make the code operate correctly...

    def get_initial(self):
        initial = super(NotificationView, self).get_initial()
        receivers = Memo.objects.filter(id=self.kwargs['pk']).values_list('receiver')
        initial['receiving_groups'] = EmployeeType.objects.filter(employee_type=receivers)
        return initial

Upvotes: 0

Iain Shelvington
Iain Shelvington

Reputation: 32294

Having a Meta on a forms.Form doesn't do anything, this is used for ModelForms

If receiving_groups should be choices of EmployeeType then it should be a ModelMultipleChoiceField

class MemoNotificationForm(forms.Form):
    receiving_groups = forms.ModelMultipleChoiceField(
        EmployeeType.objects.all(),
        widget=forms.CheckboxSelectMultiple
    )

Then you should be passing instances, or a queryset of the model in the initial

    def get_initial(self):
        initial = super(NotificationView, self).get_initial()
        initial['receiving_groups'] = EmployeeType.objects.filter(memo__id=self.kwargs['pk'])
        return initial

EDIT: As a ModelForm this could look like so

class MemoNotificationForm(forms.ModelForm):

    class Meta:
        model = Memo
        fields = ('receiver', )

View:

class NotificationView(FormView);
    form_class = MemoNotificationForm

    def get_form_kwargs(self):
        kwargs = super(NotificationView, self).get_form_kwargs()
        kwargs['instance'] = get_object_or_404(Memo, id=self.kwargs['pk'])
        return kwargs

Upvotes: 1

Related Questions