Home > Software engineering >  Cannot query "": Must be "User" instance in Django 3.2
Cannot query "": Must be "User" instance in Django 3.2

Time:09-29

I get this error from below view:

from django.shortcuts import render, redirect
from movies import models as movies_models
from django.contrib.auth import get_user_model

User = get_user_model()


def playlists_view(request):
    if (not request.user.is_authenticated) or (not request.user.is_staff):
        return redirect('Login')

    playlists = movies_models.PlayList.objects.filter(created_by=request.user).order_by('-id')

    return render(request, 'cpanel/playlists.html', {'playlists': playlists})

My playlist model is this:

from django.db import models
class PlayList(models.Model):
    type = models.PositiveSmallIntegerField(choices=type_choice, default=1, verbose_name='نوع فیلم')
    category = models.ManyToManyField(Category, related_name='Playlists', verbose_name='دسته بندی و ژانر')
    name_en = models.CharField(max_length=55, unique=True, verbose_name='نام انگلیسی')
    name_fa = models.CharField(max_length=55, unique=True, verbose_name='نام فارسی')
    summary = models.TextField(max_length=1024, verbose_name='خلاصه فیلم')
    imdb_score = models.FloatField(default=0, verbose_name='IMDB امتیاز')
    users_score = models.FloatField(default=0, verbose_name='امتیاز کاربران')
    # seen_number = models.FloatField(default=0, verbose_name='تعداد نفراتی که فیلم را مشاهده کرده اند')
    publish_status = models.CharField(max_length=55, null=True, blank=True)
    is_free = models.BooleanField(default=False, verbose_name='رایگان است')
    visit_times = models.IntegerField(default=0)
    play_times = models.IntegerField(default=0)
    year = models.CharField(max_length=4, verbose_name='سال')
    time = models.CharField(max_length=55, verbose_name='مدت زمان فیلم')
    tv_pg = models.PositiveSmallIntegerField(choices=tv_pg_choice, default=5, verbose_name='درجه بندی سنی')
    actor = models.ManyToManyField(Actor, blank=True, verbose_name='بازیگران')
    director = models.ManyToManyField(Director, blank=True, verbose_name='کارگردان')
    thumb_image = models.ImageField(null=True, blank=True, editable=True, upload_to=image_path,
                                    verbose_name='تصویر انگشتی فیلم')
    image_1920x1080 = models.ImageField(null=True, blank=True, editable=True, upload_to=image_path,
                                        verbose_name='تصویر بنر دسکتاپ فیلم')
    image_600x810 = models.ImageField(null=True, blank=True, editable=True, upload_to=image_path,
                                      verbose_name='تصویر بنر موبایل فیلم')
    country = models.ManyToManyField(Country, verbose_name='کشور')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(null=True, blank=True)
    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    users_score_n = models.IntegerField(default=0)
    users_score_p = models.IntegerField(default=0)
    trailer_url = models.CharField(max_length=512, null=True, blank=True, verbose_name='آدرس تریلر')
    page_url = models.CharField(max_length=255, null=True, blank=True, help_text='This field is Read Only')

    def __str__(self):
        return self.name_en   ' | Type: '   str(self.type)   ' | ID: '   str(self.id)

    def get_absolute_url(self):
        return reverse("playlist", kwargs={"pk": self.id, "name_en": self.name_en, "name_fa": self.name_fa})

    def save(self, *args, **kwargs):
        old_image_name = self.thumb_image.name
        super().save(*args, **kwargs)

        if self.type == 1:
            self.page_url = 'movie/'   str(self.id)   '/'   name_to_url(self.name_en)   '/' \
                              name_to_url(self.name_fa)   '/'
        else:
            self.page_url = 'series/'   str(self.id)   '/'   name_to_url(self.name_en)   '/' \
                              name_to_url(self.name_fa)   '/'
        super().save(*args, **kwargs)
        if old_image_name != self.thumb_image.name:
            image_resize(self.thumb_image.name)

but the important part of this model is this field:

created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)

And I define User like these:

from django.contrib.auth import get_user_model

User = get_user_model()

When I run django app in my localhost it's ok but in production server I get this error :(

I tried instead of using request.user, use User.objects.get(username=request.user) but I got same error in below line:

playlists = movies_models.PlayList.objects.filter(created_by=request.user).order_by('-id')

My User is a simple user model that inheritance from AbstractUser model.

Thanks for your attention. :)

CodePudding user response:

It seems that you are using a custom User class. Make sure that it is the one used in your models. As documented in Referencing the User model:

If you reference User directly (for example, by referring to it in a foreign key), your code will not work in projects where the AUTH_USER_MODEL setting has been changed to a different user model.

When you define a foreign key or many-to-many relations to the user model, you should specify the custom model using the AUTH_USER_MODEL setting

First, make sure that you correctly substituted the custom user class in the settings.py and performed the necessary migration.

...
AUTH_USER_MODEL = 'myapp.MyUser'
...

Then, try changing this (assuming the User here is not yet the result of get_user_model() because it wasn't indicated in the pasted model in the question):

created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)

To:

from django.conf import settings
...
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True)

Or:

from django.contrib.auth import get_user_model
...
created_by = models.ForeignKey(get_user_model(), on_delete=models.SET_NULL, null=True, blank=True)

Make sure that they are migrated correctly without failures:

python manage.py makemigrations
python manage.py migrate
  • Related