How To Set A Related Field To Session In Django

32 Views Asked by At

I want to implement the Web Push Notification in my current project, and I want the notification only sent to the currently logged-in sessions (i.e. devices).

Thus I define my Subscription model like below:

class Subscription(models.Model):
    device = models.CharField(max_length=100)
    session = models.OneToOneField('sessions.Session', on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    info = models.JSONField()

and the view function to save subscription:

SubscriptionForm = model form_factory(Subscription, fields=['device', 'info'])

@login_required
@require_POST
def subscr_view(request):
    form = SubscriptionForm(request.POST)
    if form.is_valid():
        form.instance.session = request.session.model
        form.instance.user = request.user
        subscr = form.save()
        return JsonResponse({'subscription': subscr.id}, status=201)
    return JsonResponse({'errors': list(form.errors.keys())})

However, when I save the form, Django complains about the session attribute:

ValueError: Cannot assign "<class 'django.contrib.sessions.models.Session'>": "Subscription.session" must be a "Session" instance.

How can i set the session attribute correctly?

2

There are 2 best solutions below

0
JimChr - R4GN4R On BEST ANSWER

Just to makethe working code clear, here it is:

from django.contrib.sessions.models import Session
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.views.decorators.http import require_POST

@login_required
@require_POST
def subscr_view(request):
    form = SubscriptionForm(request.POST)
    if form.is_valid():
        session_key = request.session.session_key
        session = get_object_or_404(Session, session_key=session_key)

        form.instance.session = session
        form.instance.user = request.user
        subscr = form.save()
        return JsonResponse({'subscription': subscr.id}, status=201)
    return JsonResponse({'errors': list(form.errors.keys())})
1
Ivan On

You have to assign an instance of Session, not the Session class, so change this line:

form.instance.session = request.session.model

to

form.instance.session = request.session