Circular Dependency Error in Django - python

Having an issue when running makemigrations/migrate with my Django project.
Getting this error:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\__init__.py", line 353, in execute_from_command_line
utility.execute()
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\base.py", line 399, in execute
output = self.handle(*args, **options)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\management\commands\migrate.py", line 139, in handle
plan = executor.migration_plan(targets)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\migrations\executor.py", line 60, in migration_plan
for migration in self.loader.graph.forwards_plan(target):
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\migrations\graph.py", line 149, in forwards_plan
self.ensure_not_cyclic(target, lambda x: (parent.key for parent in self.node_map[x].parents))
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\migrations\graph.py", line 241, in ensure_not_cyclic
raise CircularDependencyError(", ".join("%s.%s" % n for n in cycle))
django.db.migrations.exceptions.CircularDependencyError: accounts.0001_initial, projects.0001_initial
I have two apps---one called Accounts and another called Projects
for my Accounts app, here is the model:
from django.contrib.auth.models import (
AbstractBaseUser,
BaseUserManager,
PermissionsMixin
)
from django.db import models
from django.utils import timezone
from django.conf import settings
from django.db.models.signals import post_save
import os
from projects.models import Skill, Project
def avatar_upload_path(instance, filename):
return os.path.join('avatars', 'user_{0}', '{1}').format(
instance.user.id, filename)
class UserManager(BaseUserManager):
def create_user(self, email, username=None, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
username = email.split('#')[0]
user = self.model(
email=self.normalize_email(email),
username=username,
)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email,
username,
password,
)
user.is_staff = True
user.is_superuser = True
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True, default='')
date_joined = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def __str__(self):
return "#{}".format(self.username)
def get_short_name(self):
return self.username
def get_long_name(self):
return "#{} ({})".format(self.username, self.email)
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
first_name = models.CharField(max_length=40, default='', blank=True)
last_name = models.CharField(max_length=40, default='', blank=True)
bio = models.TextField(blank=True, default='')
avatar = models.ImageField('Avatar picture',
upload_to=avatar_upload_path,
null=True,
blank=True)
skills = models.ManyToManyField(Skill)
def __str__(self):
return self.user.username
#property
def get_avatar_url(self):
if self.avatar:
return '/media/{}'.format(self.avatar)
return 'http://www.gravatar.com/avatar/{}?s=128&d=identicon'.format(
'94d093eda664addd6e450d7e9881bcad'
)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
and for my Projects app here is the model. I thought that maybe since I was using a many to many field from the UserProfile to the Skill class in another app that maybe that was the issue...so i tried to run makemigrations separately on the two apps---while commenting out 'skill' from UserProfile. Didn't work. So not sure what to do now.
from django.conf import settings
from django.db import models
from django.core.urlresolvers import reverse
class Skill(models.Model):
"""User skills class."""
ANDROID = 1
DESIGNER = 2
JAVA = 3
PHP = 4
PYTHON = 5
RAILS = 6
WORDPRESS = 7
IOS = 8
SKILL_CHOICES = (
(str(ANDROID), 'Android Developer'),
(str(DESIGNER), 'Designer'),
(str(JAVA), 'Java Developer'),
(str(PHP), 'PHP Developer'),
(str(PYTHON), 'Python Developer'),
(str(RAILS), 'Rails Developer'),
(str(WORDPRESS), 'Wordpress Developer'),
(str(IOS), 'iOS Developer')
)
name = models.CharField(max_length=140, choices=SKILL_CHOICES, default='unknown')
def __str__(self):
return self.get_name_display()
class Project(models.Model):
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='project', null=True)
created_at = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=255)
description = models.TextField()
requirements = models.TextField(default='')
timeline = models.CharField(max_length=255, blank=True)
complete = models.BooleanField(default=False)
#property
def open_positions(self):
return self.positions.exclude(filled=True)
def __str__(self):
return self.title.title()
def get_absolute_url(self):
return reverse("projects:project_detail", kwargs={"pk": self.pk})
class Position(models.Model):
project = models.ForeignKey(Project, default='',related_name='positions')
name = models.CharField(max_length=140)
description = models.TextField()
skill = models.ForeignKey(Skill, default='', null=True)
filled = models.BooleanField(default=False)
def __str__(self):
return '{} - {}'.format(self.project.title.title(), self.name.title())

Your 2 migrations have a dependency on each other. Look at the generated migration for your account app and you will probably see something like this
class Migration(migrations.Migration):
dependencies = [
('projects', '0001_initial'),
]
There is probably something similar in your projects migration
You need to delete these two migration files and run makemigrations again without specifying an app name

When you have this type of problem that means you are importing classes from each other. You are using each other app model classes in Foreignkey and ManytoMany fields.
So use below way to define fields in your models.py of both app.
field = models.ForeignKey('app_name.ModelClassName',)
field = models.ManyToManyField('app_name.ModelClassName',)

Related

Why Am I getting an Integrity Error while uploading csv file to django app?

While uploading a csv file I'm getting an Integrity Error. I have a correctly working QuizApp which has models about Quiz, Questions and Answers. But I've created another app csvs to upload csv file with Questions and Answers. While I'm trying to upload a CSV file I'm getting that error. The file isn't uploaded to the website.
IntegrityError at /something/admin/csvs/csv/add/
null value in column "quiz_id" of relation "csvs_csv" violates not-null constraint
DETAIL: Failing row contains (11, csvs/example_KLOIQJK.csv, 2022-09-15 05:46:25.666689+00, f, null)
csvs.models.py
class Csv(models.Model):
file_name = models.FileField(upload_to="csvs")
uploaded = models.DateTimeField(auto_now_add=True)
activated = models.BooleanField(default=False)
csvs.forms.py
from django import forms
from csvs.models import Csv
class CsvModelForm(forms.ModelForm):
class Meta:
model = Csv
fields = ("file_name",)
csvs.views.py
from django.shortcuts import render
from django.http import HttpResponse
from .forms import CsvModelForm
# Create your views here.
def upload_file_view(request):
form = CsvModelForm(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
form = CsvModelForm()
return render(request, "csvs/import.html", {"form": form})
quiz.models.py
from django.db import models
from django.contrib.auth import get_user_model
from django.urls import reverse, reverse_lazy
import uuid
class Quiz(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
short_description = models.CharField(max_length=500)
resolution_time = models.PositiveIntegerField(
help_text="Quiz Duration in minutes", default=15
)
number_of_questions = models.PositiveIntegerField(default=1)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
is_public = models.BooleanField(default=False)
required_score_to_pass = models.IntegerField(
help_text="Required score in %", default=50
)
def __str__(self):
return f"Quiz title: {self.title}"
def get_absolute_url(self):
return reverse("quiz_detail", args=[str(self.id)])
def get_absolute_url_edit(self):
return reverse("quiz_edit", args=[str(self.id)])
def get_absolute_url_questions_edit(self):
return reverse("quiz_questions_edit", args=[str(self.id)])
def get_absolute_url_delete(self):
return reverse("quiz_delete", args=[str(self.id)])
def get_absolute_url_my_quizes(self):
return reverse("my_quiz")
def get_absolute_url_answer_edit(self):
return reverse("question_answer_edit")
def get_absolute_url_create(self):
return reverse("quiz_create")
def get_absolute_url_play(self):
return reverse("quiz_play", args=[str(self.id)])
class Question(models.Model):
quiz = models.ForeignKey(
Quiz,
on_delete=models.CASCADE,
related_name="questions",
)
content = models.CharField(max_length=255)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
def __str__(self):
return self.content
class Answer(models.Model):
content = models.CharField(max_length=255)
question = models.ForeignKey(
Question,
on_delete=models.CASCADE,
related_name="answers",
)
is_correct = models.BooleanField(default=False)
def __str__(self):
return self.content
def is_that_correct_answer(self):
return self.is_correct
class Attempt(models.Model):
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
score = models.SmallIntegerField(default=1)
has_passed = models.BooleanField(default=False)
attempt_date = models.DateTimeField(auto_now_add=True)
Any ideas?
Looks like you haven't uploaded showed whole CSV model or haven't created new migrations, because CSV model should have on more field - quiz. So either run makemigrations to remove quiz from CSV or in your form add quiz to form fields

Django ManytoManyField query does not exist

I've created models for the logic of friend list and friend request. In the FriendRequest I've defined a method which adds User relation to FriendList if accept method is called. However I'm unable to do so because of the error shown below.
I don't understand the error as I'm adding the User in the model.
views.py
friend_request = FriendRequest.objects.get(id=request_id)
if request_option == 'accept':
friend_request.accept()
if request_option == 'decline':
friend_request.decline()
models.py
class FriendList(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="user")
friends = models.ManyToManyField(User, blank=True, related_name="friends")
def add_friend(self, account):
if not account in self.friends.all():
self.friends.add(account)
self.save()
class FriendRequest(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name="sender")
receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name="receiver")
is_active = models.BooleanField(blank=False, null=False, default=True)
timestamp = models.DateTimeField(auto_now_add=True)
def accept(self):
receiver_friend_list = FriendList.objects.get(user=self.receiver)
if receiver_friend_list:
receiver_friend_list.add_friend(self.sender)
sender_friend_list = FriendList.objects.get(user=self.sender)
if sender_friend_list:
sender_friend_list.add_friend(self.receiver)
self.is_active = False
self.save()
def decline(self):
self.is_active = False
self.save()
File "C:\Users\models.py", line 77, in accept
receiver_friend_list = FriendList.objects.get(user=self.receiver)
File "C:\Python310\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Python310\lib\site-packages\django\db\models\query.py", line 496, in get
raise self.model.DoesNotExist(
friends.models.FriendList.DoesNotExist: FriendList matching query does not exist.
You are querying for a non-existing object. To avoid that error use get_or_create:
def accept(self):
receiver_friend_list, created = FriendList.objects.get_or_create(user=self.receiver)
if receiver_friend_list:
receiver_friend_list.add_friend(self.sender)
sender_friend_list = FriendList.objects.get(user=self.sender)
if sender_friend_list:
sender_friend_list.add_friend(self.receiver)
self.is_active = False
self.save()
This is what Django Docs shows and there is a pythonic way also taken from Django Docs.
try:
receiver_friend_list= FriendList.objects.get(user=self.receiver)
except FriendList.DoesNotExist:
receiver_friend_list = FriendList(user=self.receiver)
receiver_friend_list.save()

Django Postgresql Error in Production (quiz.models.Question.DoesNotExist:)

I am creating a quiz application using a guide. My application works perfectly fine in development with both sqlite3 and postgresql databases. But when pushed to production, I am faced with errors using a postgresql database. So I tried using my development sqlite3 database in production to test things out. My sqlite3 database works fine in production, but postgresql does not work in production. Initially, I thought the error is on the views level, but now I am seeing the error coming from the postgresql. Could be errors in my views or models schema. I really can't tell. The corresponding error I get when using a postgresql database in production using a linux server with gunicorn and nginx is here below, and the whole models design and views are here below too. Thanks, I appreciate your time in giving me a suitable answer to my question.
models.py
from django.db import models
import random
from account.models import Profile
from django.urls import reverse
import datetime
from django.utils import timezone
from ckeditor_uploader.fields import RichTextUploadingField
class PublishedBookManager(models.Manager):
def get_queryset(self):
return super(PublishedBookManager, self).get_queryset().filter(publish_book=True)
class Book(models.Model):
name = models.CharField(max_length=120)
description = models.TextField()
created_by = models.ForeignKey(Profile, default=1, null=True, on_delete=models.SET_NULL)
number_of_questions = models.IntegerField()
number_of_sections = models.IntegerField()
time = models.IntegerField(help_text="duration of the quiz in minutes")
required_score_to_pass = models.IntegerField(help_text="required score in %")
start_date = models.DateTimeField(default=timezone.now)
publish_book = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
objects = models.Manager()
published = PublishedBookManager()
def __str__(self):
return f"{self.name}"
def get_absolute_url(self):
return reverse('quiz:book-detail-view', args=[self.pk])
class PublishedQuizManager(models.Manager):
def get_queryset(self):
return super(PublishedQuizManager, self).get_queryset().filter(publish_quiz=True)
class Quiz(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE, blank=True, null=True)
name = models.CharField(max_length=120)
description = models.TextField()
created_by = models.ForeignKey(Profile, default=1, null=True, on_delete=models.SET_NULL)
number_of_questions = models.IntegerField()
time = models.IntegerField(help_text="duration of the quiz in minutes")
required_score_to_pass = models.IntegerField(help_text="required score in %")
completed_users = models.ManyToManyField(Profile, blank=True, related_name='completed_users_quiz')
publish_quiz = models.BooleanField(default=False)
start_date = models.DateTimeField(default=timezone.now)
deadline_date = models.DateTimeField(default=timezone.now)
date_created = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True)
objects = models.Manager()
published = PublishedQuizManager()
def __str__(self):
return f"{self.book.name} = {self.name}"
def get_questions(self):
questions = list(self.question_set.all())
random.shuffle(questions)
return questions[:self.number_of_questions]
class Meta:
verbose_name_plural = 'Quizes'
def get_absolute_url(self):
return reverse('quiz:quiz-view', kwargs={'book_pk': self.book.pk, "pk": self.pk})
class Question(models.Model):
# text = models.TextField()
text = RichTextUploadingField(unique=True)
second_text = models.TextField()
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.text)
def get_answers(self):
return self.answer_set.all()
# def get_absolute_url(self):
# return reverse('quiz:quiz-view', kwargs={'question_pk': self.pk,})
class Answer(models.Model):
text = models.CharField(max_length=255)
correct = models.BooleanField(default=False)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"question: {self.question.text}, answer: {self.text}, correct: {self.correct}"
class Result(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
user = models.ForeignKey(Profile, on_delete=models.CASCADE)
score = models.FloatField()
date_created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.pk)
views.py
def save_quiz_view(request, pk, book_pk):
# if request.user in
quiz = Quiz.objects.get(pk=pk)
# Submition of result only occurs if a user is not in the completed users field. If they are already
# in the completed users ManyToMany field, then it won't save. But if not, it will save.
if request.is_ajax() and not request.user.profile in quiz.completed_users.all():
questions = []
data = request.POST
data_ = dict(data.lists())
data_.pop('csrfmiddlewaretoken')
for _k in data_.keys():
if Question.objects.all():
# print('key: ', k)
k = _k
question = Question.objects.get(text=k)
questions.append(question)
user = request.user.profile
quiz = Quiz.objects.get(pk=pk)
if request.user.is_authenticated:
if not user in quiz.completed_users.all():
quiz.completed_users.add(user)
score = 0
multiplier = 100 / quiz.number_of_questions
results = []
correct_answer = None
for q in questions:
a_selected = request.POST.get(q.text)
if a_selected != "":
question_answers = Answer.objects.filter(question=q)
for a in question_answers:
if a_selected == a.text:
if a.correct:
score += 1
correct_answer = a.text
else:
if a.correct:
correct_answer = a.text
results.append({str(q): {'correct_answer': correct_answer, 'answered': a_selected}})
else:
results.append({str(q): 'not answered'})
score_ = score #* multiplier
Result.objects.create(quiz=quiz, user=user, score=score_)
if score_:#>= quiz.required_score_to_pass:
return JsonResponse({'passed': True, 'score': score_, 'results': results})
else:
return JsonResponse({'passed': False, 'score': score_, 'results': results})
Error
django#UniqueAsf2:~/src$ python3 manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
October 26, 2021 - 03:57:12
Django version 3.2.8, using settings 'asf.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
[26/Oct/2021 03:57:18] "GET /quiz/1/1/ HTTP/1.1" 200 8065
Not Found: /quiz/1/1/assets/vendors/boxicons/css/boxicons.min.css
[26/Oct/2021 03:57:18] "GET /quiz/1/1/assets/vendors/boxicons/css/boxicons.min.css HTTP/1.1" 404 5612
[26/Oct/2021 03:57:18] "GET /quiz/1/1/data/ HTTP/1.1" 200 101
Internal Server Error: /quiz/1/1/save/
Traceback (most recent call last):
File "/home/django/.local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/django/.local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/django/src/quiz/views.py", line 108, in save_quiz_view
question = Question.objects.get(text=_k)
File "/home/django/.local/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/django/.local/lib/python3.9/site-packages/django/db/models/query.py", line 435, in get
raise self.model.DoesNotExist(
quiz.models.Question.DoesNotExist: Question matching query does not exist.
Your data in Question is not stored in simple text because you are using RichTextUploadingField which converts text into HTML format for handling text fomatting. Because of this you can't directly compare two strings or run search over it.
Try using icontains for checking string in your field. This might not work in all cases so you'll have to handle that accordingly.
questions = Question.objects.filter(text__icontains=k)
for question in questions:
# Handle questions here

Cannot login using user model Django

I have inserted data using User.objects.create() to the the User model and I cannot seem to login using the correct email and password. Whenever I try to Django always returns "wrong username or password" even though I have checked that the user exist using Django ORM.
However, if I register using the link on the webpage, I can login but it created a user with a blank username so I can only create one user, change the username using Django ORM, and then create another one. Is there anything I did wrong? Thanks in advance
Here is my User model:
from django.contrib.auth.models import AbstractUser, UserManager
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import Q
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
class MyUserManager(UserManager):
def create_user(self, *args, **kwargs):
"""
Set username field as email.
"""
kwargs['email'] = self.normalize(kwargs['email'])
kwargs['username'] = self.normalize(kwargs['email'])
return super(MyUserManager, self).create_user(*args, **kwargs)
#python_2_unicode_compatible
class User(AbstractUser):
ADMIN_AREA = 'aa'
FINANCE = 'fn'
RELATIONSHIP_MANAGER = 'rm'
BUSINESS_MANAGER = 'bm'
SENIOR_BUSINESS_MANAGER = 'sbm'
ADMIN_INTERNAL = 'brm'
POSITION_CHOICES = {
(ADMIN_INTERNAL, 'Admin Internal'),
(SENIOR_BUSINESS_MANAGER, 'Senior Business Manager'),
(BUSINESS_MANAGER, 'Business Manager'),
(RELATIONSHIP_MANAGER, 'Relationship Manager'),
(FINANCE, 'Finance'),
(ADMIN_AREA, 'Admin Area')
}
name = models.CharField(_('Nama Lengkap'), blank=True, max_length=255)
phone = models.CharField('Nomor telepon', blank=True, max_length=20)
phone_alt = models.CharField('Nomor telepon alternatif', blank=True, max_length=20)
date_of_birth = models.DateField('Tanggal lahir', null=True)
leader = models.ForeignKey('self', on_delete=models.PROTECT, null=True, blank=True)
email = models.EmailField(max_length=255, unique=True)
position = models.CharField('Posisi', max_length=3, choices=POSITION_CHOICES, blank=True)
branch = models.ForeignKey(Branch, on_delete=models.PROTECT, blank=True, null=True)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
def get_all_children(self, include_self=True):
"""Get all relationship manager under one user until second level."""
childs = User.objects.filter(leader=self)
if include_self:
childs = User.objects.filter(Q(id=self.id) | Q(leader=self))
return childs
objects = MyUserManager()
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('users:detail', kwargs={'email': self.email})
This is the script I used to insert the data into the model. Basically what I did is import a csv file and create a user based on the items in the file
import csv
from pertama.users.models import User
with open('zz_supporting_files/data.csv') as csvfile:
reader = csv.DictReader(csvfile)
password = "first123"
for row in reader:
name = row['NAMA']
if row['EMAIL'] == "":
email = name.split(' ')[0].lower() + "#firstone.com"
else:
email = row['EMAIL']
if row['JABATAN'] == "MARKETING":
position = "rm"
else:
position = "bm"
print(name, email, password, position) # for debugging
user = User.objects.create(
name=name,
email=email,
password=password,
username=email,
position=position,
)
user.save()
User.objects.all() # Debugging only
EDIT: Inserted the code for CSV file
You just need to tweak your command to User.objects.create_user() as this will take care of setting password correctly and you will be able to login your webpage.
Don't use User.objects.create()
The correct set of commands should be:
$ pyhton manage.py shell
Then in shell:
>>> from django.contrib.auth.models import User
>>> user=User.objects.create_user('foo', password='bar')
#Only if you want user to have superuser access, else skip this
>>> user.is_superuser=True
>>> user.is_staff=True
>>> user.save()

Django REST Framework: Manager isn't available; User has been swapped for 'api.User'

I'm experiencing a problem with Django users and the Django REST Framework.
In my settings I have defined a custom user model:
AUTH_USER_MODEL = 'api.User'
In my sandbox.api package I have defined this model in the models.py file:
from django.db import models
from django.core.exceptions import ValidationError
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import UserManager
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _
from django.core import validators
from django.core.mail import send_mail
from django.utils import timezone
from django.core.exceptions import NON_FIELD_ERRORS
from random import randrange
class User(AbstractBaseUser, PermissionsMixin):
"""
Custom user class
"""
username = models.CharField(_('username'), max_length=20, unique=True,
help_text=_('Required. 30 characters or fewer. Letters and digits only.'),
validators=[
validators.RegexValidator(r'^[a-z0-9A-Z]{1,20}$', _('Enter a valid username.'), 'invalid')
])
email = models.EmailField(_('email address'), max_length=60, blank=False, null=False, unique=True)
is_staff = models.BooleanField(_('staff status'), default=False,
help_text=_('Designates whether the user can log into this admin '
'site.'))
is_active = models.BooleanField(_('active'), default=True,
help_text=_('Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.'))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
def email_user(self, subject, message, from_email=None, **kwargs):
send_mail(subject, message, from_email, [self.email], **kwargs)
def clean(self):
errors = {}
id = self.id
if not id:
id = 0
n = len(list(User.objects.raw('SELECT id FROM auth_user WHERE LOWER(username) = LOWER(%s) AND id != %s', [self.username, id])))
if n > 0:
errors['username'] = 'User with this username already exists.'
n = len(list(User.objects.raw('SELECT id FROM auth_user WHERE LOWER(email) = LOWER(%s) AND id != %s', [self.email, id])))
if n > 0:
errors['email'] = 'User with this e-mail address already exists.'
if len(errors) > 0:
raise ValidationError(errors)
def save(self, *args, **kwargs):
self.username = self.username.lower()
self.email = self.email.lower()
super(User, self).save(*args, **kwargs)
def __unicode__(self):
return u'%s' % self.username
class Meta:
db_table = 'auth_user'
verbose_name = _('user')
verbose_name_plural = _('users')
abstract = False
And in my sandbox.api package I have defined a serializer in the serializers.py file:
class UserSerializer(ExtSerializer):
"""
User serializer
"""
name = serializers.SerializerMethodField('get_name')
description = serializers.SerializerMethodField('get_description')
url = serializers.SerializerMethodField('get_url')
location = serializers.SerializerMethodField('get_location')
facebook_id = serializers.SerializerMethodField('get_facebook_id')
twitter_id = serializers.SerializerMethodField('get_twitter_id')
path = serializers.SerializerMethodField('get_path')
feed = serializers.HyperlinkedIdentityField(lookup_field='username', view_name='user-feed-collection')
timeline = serializers.HyperlinkedIdentityField(lookup_field='username', view_name='user-timeline-collection')
followers = serializers.HyperlinkedIdentityField(lookup_field='username', view_name='user-follower-collection')
following = serializers.HyperlinkedIdentityField(lookup_field='username', view_name='user-following-collection')
posts_count = serializers.SerializerMethodField('get_posts_count')
followers_count = serializers.SerializerMethodField('get_followers_count')
following_count = serializers.SerializerMethodField('get_following_count')
def get_path(self, user):
request = self.context['view'].request
return reverse_lazy('user-singleton', kwargs={
"username": user.username
}, request=request, format=FORMAT_SUFFIX)
def get_facebook_id(self, user):
return user.profile.facebook_id
def get_twitter_id(self, user):
return user.profile.twitter_id
def get_posts_count(self, user):
return Post.objects.filter(author__pk=user.pk).count()
def get_following_count(self, user):
return Follower.objects.filter(follower=user.pk).count()
def get_followers_count(self, user):
return Follower.objects.filter(following=user.pk).count()
def get_name(self, user):
return user.profile.name
def get_description(self, user):
return user.profile.description
def get_url(self, user):
return user.profile.url
def get_location(self, user):
return user.profile.location
class Meta:
model = User
fields = ('path', 'id', 'username', 'name', 'description', 'url', 'location', 'is_active',
'facebook_id', 'twitter_id', 'email',
'feed', 'timeline', 'following', 'followers',
'posts_count', 'following_count', 'followers_count')
I'm 100% that the URL bindings are correct for the API. When I try to GET a list of users I get the following error however:
Manager isn't available; User has been swapped for 'api.User'
Does anybody have any idea about what's going on here? I'm using Django 1.7.1 on Python 2.7.6.
Thanks in advance for any help!
Kind regards,
K.
Instead of referring to User directly, you should reference the user
model using django.contrib.auth.get_user_model(). This method will
return the currently active User model – the custom User model if one
is specified, or User otherwise.
Kinda late but nonetheless...

Categories

Resources