Home > Enterprise >  how to pass model data to template using a function based view?
how to pass model data to template using a function based view?

Time:07-22

I have a simple model for a Group:

class Group(models.Model):
   leader = models.ForeignKey(User, on_delete=models.CASCADE)
   name = models.CharField(max_length=55)
   description = models.TextField()
   joined = models.ManyToManyField(User, blank=True)
       email_list = ArrayField(
        models.CharField(max_length=255, blank=True),
        blank=True,
        default=list,
    )

With four views for it: DetailView, UpdateView, DeleteView, and send_notifications. The first two are class based and the last is function based. This is where I'm having an issue.

When I move from my base.html to any of my class based views:

path('group/<int:pk>/', GroupDetail.as_view(), name='group_detail'),
path('group/<int:pk>/edit/', UpdateGroup.as_view(), name='update_group'),
path('group/<int:pk>/delete/', DeleteGroup.as_view(), name='delete_group'),

I'm able to pass the specific model's data using it's primary key:

<a href="{% url 'group_detail' group.pk %}">DETAILS</a>
<a href="{% url 'update_group' group.pk %}">EDIT</a>
<a href="{% url 'delete_group' group.pk %}">DELETE</a>

So when I'm in one of these three views I'm able to render things like {{group.name}} or {{group.description}}, but when I go to my function based view:

def notifications(request, pk):
    group = Group.objects.get(id=pk)
    if request.method == 'POST':
        subject = request.POST['subject']
        message = request.POST['message']
        recipients = group.email_list
        for recipient in recipients:
            send_mail (
                subject,
                message,
                NOTIFICATION_EMAIL,
                [recipient],
                fail_silently=False
            )
        return render(request, 'send_notifications.html', {'subject': subject, 'message': message})
    else:
        return render(request, 'send_notifications.html', {})

via its url:

path('group/<int:pk>/notifications/', notifications, name='send_notifications'),

and link:

<a href="{% url 'send_notifications' group.pk %}">SEND NOTIFICATIONS</a>

I'm not able to render any of the Group's data. Is there something about a function based view vs a class based view that's causing this? Every other part of the view works fine, I just can't access any of the specific Group's data like I can in the class based views.

The only reason I'm using the function based view for sending notifications is because I'm using send_mail and django's built-in email model. Should I create a class base view for sending notifications? Or is there a way to pass the data to the template using my notifications function based view?

CodePudding user response:

The key concept here is context. Context is handled for you in class based views (though it is extendable), but in a function based view you need to pass it along to the template explicitly. You're actually already doing this in...

 return render(request, 'send_notifications.html', {'subject': subject, 'message': message})

There you are passing 'subject' and 'message' along as context. Passing along group is as simple as adding the key and the value to the context object.

 return render(request, 'send_notifications.html', {'subject': subject, 'message': message, 'group': group})

or

 return render(request, 'send_notifications.html', {'group': group})

in the unPOST version.

  • Related