BUG - String model references must be of the form 'app_label.ModelName'. - make migration

first of all, this is my first time using this forum. I am sorry if its the wrong place.

the problem,

I tried to add a custom user to django, I followed this tutorial : LINK IN PASTE BIN BECAUSE I CANT POST 2 LINKS - sorry if links not allowed, and added my own stuff.

when I try to make migrations I get this annoying error

ValueError: Invalid model reference ‘main.website.NewUser’. String model references must be of the form ‘app_label.ModelName’.
and after some digging I found this error

app_label, model_name = model.split(".")
ValueError: too many values to unpack (expected 2)

I have found this stackover flow post -

, which seems to solver it but I can not spot the problem in my code, after a whole night of search I would like another set of eyes to take a look.

code - all classes are in there one after another.

thanks in advance, good night :frowning:

Unfortunately, your pastebin link just shows the text of all your files, with no indications of file names or directory structures.

You can post code directly here in the forum. When you do, surround it by lines consisting of three backtick - ` characters. This means you’d have a line of ```, then your code, then another line of ```. This forces the forum to keep your code formatted properly.

To offer advice, we’ll probably need to see the module that is throwing that error, a description of how your project is structured in directories, and the name of the file and directory in which the model exists. It would also be helpful if you were to post the full error messages received, also enclosed between lines of ```.

thanks, i’ll try to make it clear.

Basically I’m doing “udemy” website.
I have a user, which have general information (name email etc) and have courses which are also an db class.

the db structure looks like -
USER :
information
courses → course
course :
information (name id etc) lectures → lecture
lecture :
information
video

I was trying to extend the django user to have more inputs, first of all I made Userclass im model.py (the whole app is in main_website app) then i created createsuperuse and create user as the doucomantion says .
I installed the app and the USER MODEL in settings .py

settings.py :

"""
Django settings for ben_gurion_bkal project.

Generated by 'django-admin startproject' using Django 3.2.6.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-k@q#fs40xdi%cmy5dg*4_27&56#42u=ag&a4ws13o((6@80w2l'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'main_website',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'ben_gurion_bkal.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR/"templates"],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'ben_gurion_bkal.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    BASE_DIR/"static"

]


# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

AUTH_USER_MODEL = 'main.website.NewUser'

models.py


class CustomAccountManager(BaseUserManager):

    def create_superuser(self, email, user_name, first_name,last_name,phone_number, password, **other_fields):

        other_fields.setdefault('is_staff', True)
        other_fields.setdefault('is_superuser', True)
        other_fields.setdefault('verified_email', True)

        if other_fields.get('is_staff') is not True:
            raise ValueError(
                'Superuser must be assigned to is_staff=True.')
        if other_fields.get('is_superuser') is not True:
            raise ValueError(
                'Superuser must be assigned to is_superuser=True.')

        return self.create_user(email, user_name, first_name,last_name,phone_number, password, **other_fields)

    def create_user(self, email, user_name, first_name,last_name,phone_number, password, **other_fields):

        if not email:
            raise ValueError(_('You must provide an email address'))

        email = self.normalize_email(email)
        user = self.model(email=email, user_name=user_name,
                          first_name=first_name,last_name=last_name,phone_number=phone_number **other_fields)
        user.set_password(password)
        user.save()
        return user


class lecture(models.Model):
    name = models.CharField(max_length=50)
    video = models.FileField(upload_to='videos/')

class course_section(models.Model):
    name = models.CharField(max_length=50)
    description  = models.CharField(max_length=50)
    lectures = models.ForeignKey(lecture,on_delete=models.SET_NULL,related_name="course_section",null=True)

class course(models.Model):
    name = models.CharField(max_length=50)
    description  = models.CharField(max_length=500)
    price = models.IntegerField()
    course_img = models.ImageField(upload_to="images")
    course_sections = models.ManyToManyField(course_section)

    def __str__(self) -> str:
        return f"{self.name} - {self.price}$"

class semester(models.Model):
    name = models.CharField(max_length=50)
    semester_courses = models.ForeignKey(course,on_delete=models.SET_NULL,related_name="semester",null=True)



class degree(models.Model):
    name = models.CharField(max_length=50)
    semesters = models.ForeignKey(semester,on_delete=models.SET_NULL,related_name="degree",null=True)
    university = models.CharField(max_length=50)




class NewUser(AbstractBaseUser, PermissionsMixin):

    email = models.EmailField(_('email address'), unique=True)
    user_name = models.CharField(max_length=150, unique=True)
    first_name = models.CharField(max_length=150, blank=True)

    verified_email = models.BooleanField(default=False)
    last_name = models.CharField(max_length=50)
    user_image = models.ImageField(upload_to="images",null=True)
    phone_number = models.CharField(max_length=12)
    user_degree = models.ForeignKey(degree,on_delete=models.SET_NULL,related_name="users",null=True)
    writen_courses = models.ForeignKey(course,related_name='author',on_delete=models.SET_NULL,null=True)
    purchased_courses = models.ManyToManyField(course,related_name='course_users')

    is_staff = models.BooleanField(default=False)

    objects = CustomAccountManager()
   
    USERNAME_FIELD = user_name
    REQUIRED_FIELDS = ['user_name', 'first_name']
    def __str__(self):
        return self.user_name

as far as i understand, this line in settings.py file this is the problem
AUTH_USER_MODEL = 'main.website.NewUser

The directory name you’ve identified is main_website, so the reference would be main_website.NewUser.

thank you so much, its probbly the lack of sleep :slight_smile:

I have another problems,

I have set Users to have purcushed courses as a many to many relationship. it seems like every time i add a new user he gets all the courses instantly.

new user that just got added

code :

models

from django.db import models
from django.db.models.deletion import CASCADE, DO_NOTHING
from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin,BaseUserManager
from django.utils.translation import gettext_lazy as _





class CustomAccountManager(BaseUserManager):

    def create_superuser(self, email, first_name,last_name,phone_number, password, **other_fields):

        other_fields.setdefault('is_staff', True)
        other_fields.setdefault('is_superuser', True)
        other_fields.setdefault('verified_email', True)

        if other_fields.get('is_staff') is not True:
            raise ValueError(
                'Superuser must be assigned to is_staff=True.')
        if other_fields.get('is_superuser') is not True:
            raise ValueError(
                'Superuser must be assigned to is_superuser=True.')

        return self.create_user(email, first_name,last_name,phone_number, password, **other_fields)

    def create_user(self, email, first_name,last_name,phone_number, password, **other_fields):

        if not email:
            raise ValueError(_('You must provide an email address'))

        email = self.normalize_email(email)
        user = self.model(email=email,
                          first_name=first_name,last_name=last_name,phone_number=phone_number ,**other_fields)
        user.set_password(password)
        user.save()
        return user


class lecture(models.Model):
    name = models.CharField(max_length=50)
    video = models.FileField(upload_to='videos/')

class course_section(models.Model):
    name = models.CharField(max_length=50)
    description  = models.CharField(max_length=50)
    lectures = models.ForeignKey(lecture,on_delete=models.SET_NULL,related_name="course_section",null=True)

class course(models.Model):
    name = models.CharField(max_length=50)
    description  = models.CharField(max_length=500)
    price = models.IntegerField()
    course_img = models.ImageField(upload_to="images")
    course_sections = models.ManyToManyField(course_section)

    def __str__(self) -> str:
        return f"{self.name} - {self.price}$"

class semester(models.Model):
    name = models.CharField(max_length=50)
    semester_courses = models.ForeignKey(course,on_delete=models.SET_NULL,related_name="semester",null=True)



class degree(models.Model):
    name = models.CharField(max_length=50)
    semesters = models.ForeignKey(semester,on_delete=models.SET_NULL,related_name="degree",null=True)
    university = models.CharField(max_length=50)




class NewUser(AbstractBaseUser, PermissionsMixin):

    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(max_length=150)
    last_name = models.CharField(max_length=50)
    phone_number = models.CharField(max_length=12)

    verified_email = models.BooleanField(default=False,blank=True)
    user_image = models.ImageField(upload_to="images",blank=True)
    user_degree = models.ForeignKey(degree,on_delete=models.DO_NOTHING,related_name="users",blank=True,null=True)
    writen_courses = models.ForeignKey(course,related_name='author',on_delete=models.DO_NOTHING,blank=True,null=True)
    purchased_courses = models.ManyToManyField(course,related_name='course_users',blank=True)

    is_staff = models.BooleanField(default=False)

    objects = CustomAccountManager()
    USERNAME_FIELD = 'email'

    REQUIRED_FIELDS = ['first_name',"last_name","phone_number"]
    def __str__(self):
        return self.first_name+self.last_name

it happends even if i add via the admin menu.

  1. how can i delete many to many connection, for example if i want to remove dsf 2$ from the user?
    thanks alot of the help !
    image|690x417

That list does not mean that those entities are related. Those are the list of possible related items.

What you’re looking at is a multi-select list.

To establish / create that relationship, you need to select one or more of those items. (Hold down the Control (or Command on a Mac) to select more than one.)

See The Django admin site | Django documentation | Django

thanks again,
one last question I want that every user will have purchases which points to bundle which points to the actual content. now the relation ship between user and purchases need to be one to many,
every user can have many purchases but every purchase have one and only “buyer”.

I designed it like so :

class purchase(models.Model):
    purchase_time = models.TimeField(auto_now=True)
    purchase_content = models.ManyToManyField(bundle,related_name='bundle_purchase',blank=True)

class NewUser(AbstractBaseUser, PermissionsMixin):

    email = models.EmailField(_('email address'), unique=True)
    first_name = models.CharField(max_length=150)
    last_name = models.CharField(max_length=50)
    phone_number = models.CharField(max_length=12)

    verified_email = models.BooleanField(default=False,blank=True)
    user_image = models.ImageField(upload_to="images",blank=True)
    user_degree = models.ForeignKey(degree,on_delete=models.DO_NOTHING,related_name="users",blank=True,null=True)
    writen_courses = models.ForeignKey(course,related_name='author',on_delete=models.DO_NOTHING,blank=True,null=True)

    purchases = models.ForeignKey(purchase,related_name='user',default=None,null=True,blank=True,on_delete=models.DO_NOTHING)
    is_staff = models.BooleanField(default=False)

    objects = CustomAccountManager()
    USERNAME_FIELD = 'email'

    REQUIRED_FIELDS = ['first_name',"last_name","phone_number"]
    def __str__(self):
        return self.first_name+self.last_name
class bundle(models.Model):
    name = models.CharField(max_length=50)
    description  = models.CharField(max_length=500)
    price = models.IntegerField()
    bundle_img = models.ImageField(upload_to="images")
    bundle_content = models.ManyToManyField(course,related_name='course_bundles',blank=True)

but it seems like it makes it many to one - every user have one purchase and every purchase have mulitpal users. is there any way to change it without moving the purchases variable to the class purchase.

image

thanks !

No, the “Many” side of a many-to-one relationship is always the side with the foreign key.

so how would you design the data structure?

I have course that have a lot of sections, each section has a lot of lectures.
when admin created a section I want him to be able to choose what videos will the section have, not to go to each lecture one by one and set it to a specific section.

Don’t confuse the implementation of the UI with the data structures required to support the application.

You can create the UI to display the list of “available” videos and allow the admin to select from them.

another question.
I want to save if a user finshed watching a lecture (video).
how would you suggest to save the information in the db?

  1. each lecture will have a a field such as done watching. and every time I will check if a specific user watched the video I will querry and look if he is in the list.
  2. each player will have a variable such as video_watched ?