Nothing here
Nothing here

Reputation: 2393

How to initialize form with some parameters of model instance

I would like be able to send SMS/Email notifications manually using the groups/users of a model instance. Let's say the model looks like this:

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

I pass the object instance to the view:

path('<int:pk>/notify', NotificationView.as_view(), name='memos-notify'),

The form and the view are where I am having trouble. I figure I should be able to just pass the forms initial fields right there in the view:

class NotificationView(FormView):
    template_name = 'memos/notification_form.html'
    form_class = MemoNotificationForm
    success_url = reverse_lazy('overview')

    def get_initial(self):
        initial = super(NotificationView, self).get_initial()
        memo = Memo.objects.filter(id=id)
        initial['receiving_groups'] = memo.receiver.all()
        return initial

And the form looks like this:

class MemoNotificationForm(forms.Form):
    class Meta:
        fields = [
            'receiving_groups'
        ]

    receiving_groups = forms.MultipleChoiceField(
        required=False,
        widget=forms.CheckboxSelectMultiple)

*Note: the receiving_groups will be the ones receiving the notification. Once the form is valid I will apply a send_sms method send it.

TypeError: int() argument must be a string, a bytes-like object or a number, not 'builtin_function_or_method'

Do I need to initialize the queryset in the form? Would appreciate it if someone could paint me a clear picture of the why and how here. Thank you!

Upvotes: 1

Views: 54

Answers (1)

JPG
JPG

Reputation: 88619

The error is because of this line,

memo = Memo.objects.filter(id=id)

Here, in your scope, the id becoming python's built-in fucntion and hence the error.

To access the URL parameter, you should use self.kwargs attribute, as below

class NotificationView(FormView):
    template_name = 'memos/notification_form.html'
    form_class = MemoNotificationForm
    success_url = reverse_lazy('overview')

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

You can find the working example from the official Django documentaion here, Dynamic filtering

Upvotes: 1

Related Questions