Django - ValueError at /selected-events/ Cannot assign ... must be a "Profile" instance
I have a Django project that consists of, essentially, 3 datasets: auth User
(plus a Profile
dataset), mem_ev
and Events
such that User
--< mem_ev
>-- Event
, ie a classic many to many relationship such that members can go to many events and an event can be visited by many members.
I want to update the mem_ev
dataset with the 'events to be attended' selected by a member, but it's not working.
my models.py
file is:
from django.db import models
from django.utils.text import slugify
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE) # Delete profile when user is deleted
event_count = models.IntegerField(default=0)
def __str__(self):
return f'{self.user.username} Profile' #show how we want it to be displayed
class Event(models.Model):
title = models.CharField(max_length=50)
slug = models.SlugField(max_length=50,default="", null=False)
description = models.TextField()
cost = models.DecimalField(max_digits = 5, decimal_places = 2, default = 0.0)
event_date = models.DateTimeField(null=True,blank=True)
attendees = models.IntegerField(default=0)
class Meta:
ordering = ['event_date']
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Event, self).save(*args, **kwargs)
class Meta:
ordering = ['event_date']
def __str__(self):
return self.title
class mem_ev(models.Model):
member_id = models.ForeignKey("Profile",on_delete=models.CASCADE)
event_id = models.ForeignKey("Event",on_delete=models.CASCADE)
is_attending = models.BooleanField(default=False)
amt_paid = models.DecimalField(max_digits = 5, decimal_places = 2, default = 0.0)
date_paid = models.DateTimeField(null=True,blank=True)
The relevant part of my views.py
file is:
from django.contrib.auth.models import User
from .models import Event, mem_ev, Profile
from django.contrib.auth import get_user_model
...
def selected_events(request):
user = request.user
member = Profile.objects.get(user_id=user.id)
print(f'Member id = {member.id}')
deletes = mem_ev.objects.filter(member_id=member.id)
deletes.delete()
for event in request.POST.getlist('events'):
e = mem_ev(member_id=member.id,event_id=event) <==== this is the bit Django doesn't like
e.save()
messages.success(request, 'Your Event Selections have been updated')
return render(request, 'wf/about.html')
The error I'm getting is:
ValueError at /selected-events/
Cannot assign "14": "mem_ev.member_id" must be a "Profile" instance.
...
/home/dconran/django/mysite/wf/views.py, line 112, in selected_events
e = mem_ev(member_id=member.id,event_id=event)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'14' is the User Profile user_id
which is the same as when I added records using the Admin site. I've tried changing line 112 in views.py
to e = mem_ev(profile__member_id=member.id,event_id=event)
but it still came up with an error.
What am I doing wrong?
To fix your problem you need to pass an instance of Profile
as the member_id
value:
e = mem_ev(member_id=member, event_id=event)
There is another option to solve your problem. From documentation:
Behind the scenes, Django appends
"_id"
to the field name to create its database column name.
This means you can set the related object like this:
e = mem_ev(member_id_id=member.id, event_id=event)
This option is often preferable when you don't need to retrieve the related model instance from the database, but you know its primary key.
The same goes for event_id=event
, if event
is a primary key, then use: e = mem_ev(member_id_id=member.id, event_id_id=event)
.