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

Вернуться на верх