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?
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.