Need help in django model - django

I have written a model for my django project.
This is my model
from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.utils.crypto import get_random_string
from django.db import models
from django.contrib.auth.models import(
BaseUserManager,
AbstractBaseUser,
PermissionsMixin,
)
def generate_vid():
"""Generates a vid for the users"""
not_unique = True
while not_unique:
vid = get_random_string(10, 'abcdefg0123456789')
if not User.objects.filter(v_id = vid).exists():
not_unique=False
return vid
class UserManager(BaseUserManager):
"""Model for user manager"""
def create_user(self, username, password, **params):
"""Create and return a user"""
u_type = params.pop('usertype','v')
params.update({'usertype':u_type})
p_username = params.pop('parent_username', 0)
if(u_type=='v'):
pass
else:
parent_id = User.objects.filter(username = p_username).values_list('v_id')
params.update({'parent_id': parent_id})
user = self.model(username=username, **params)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, password, **params):
"""Create and return a user"""
params.setdefault('is_staff',True)
params.setdefault('is_superuser',True)
params.setdefault('is_active',True)
if params.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if params.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(username, password, **params)
class User(AbstractBaseUser, PermissionsMixin):
"""Models for user"""
v_id = models.CharField(
max_length=10,
default=generate_vid,
primary_key = True,
)
username = models.CharField(max_length=20, unique=True)
email = models.EmailField(blank=True, unique = True)
parent_id = models.ForeignKey('User', on_delete=models.SET_DEFAULT, default=0)
usertype = models.CharField(max_length=1, choices=[('f', 'family'), ('v', 'veteran')])
REQUIRED_FIELDS = ['usertype']
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
USERNAME_FIELD = 'username'
objects = UserManager()
def __str__(self):
return self.username
Now I want to impose the condition while creating a user such that every time I provide usertype=f, and I provide a username(say username='Test")
the parent_id of that particular entry is automatically set as the v_id of the username provided.
The parent_id is a self referential foreignkey.
This is the error showing while testing the feature
File "/py/lib/python3.9/site-packages/rest_framework/serializers.py", line 205, in save
self.instance = self.create(validated_data)
File "/app/user/serializers.py", line 17, in create
return get_user_model().objects.create_user(**validated_data)
File "/app/base/models.py", line 39, in create_user
user = self.model(username=username, **params)
File "/py/lib/python3.9/site-packages/django/db/models/base.py", line 485, in __init__
_setattr(self, field.name, rel_obj)
File "/py/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
raise ValueError(
ValueError: Cannot assign "<QuerySet []>": "User.parent_id" must be a "User" instance.

I think you can try signals to set data after creating a user account. You can choose from several types, but I would recommend you focus on pre_save and post_save.
UPDATE
I wrote examples, but the website will probably better illustrate it. In general, there are quite a few signals, but the most commonly used are pre_save and post_save.
#2 UPDATE
Try use a first or latest. Details in documentation.
parent_id = User.objects.filter(username = p_username).first()

Related

How instanciate table in createsuperuser

I have two tables Employee and Sector, the employee table has for foreign key the sector code (sectorCode) property of the Sector table. The Employee table inherits from the AbstractBaseUser class.
I would like to create a superuser with the command python manage.py createsuperuser.
I get an error: ValueError: Cannot assign "'Code1'": "Employee.sectorCode" must be a "Sector" instance.
(I added in the Sector table a row NameSector1; Code1)
I input these values:
λ python manage.py createsuperuser
registrationNumber: 001
Name: TestN1
FirstName: TestFN1
sectorCode: Code1
Password: ...
Error ...
How can I instantiate sector class in dialog ?
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyUserManager(BaseUserManager):
def create_user(self, registrationNumber, firstName, name, sectorCode, password=None):
if not firstName: raise ValueError("firstName required")
if not name: raise ValueError("name required")
if not registrationNumber: raise ValueError("registrationNumber required")
if not sectorCode: raise ValueError("sectorCode required")
user=self.model(firstName = firstName, name = name, registrationNumber = registrationNumber, sectorCode = sectorCode)
user.set_password(password); user.save()
return user
def create_superuser(self, firstName, name, registrationNumber, sectorCode, password=None):
user=self.create_user(firstName = firstName, name = name, registrationNumber = registrationNumber, sectorCode = sectorCode, password = password)
user.is_admin=True; user.is_superuser=True
user.save()
return user
class Sector(models.Model):
nameSector = models.CharField(verbose_name = "nameSector", max_length=50)
sectorCode = models.CharField(verbose_name = "sectorCode", max_length=3, primary_key=True)
class Meta: db_table = "Sector"
class Employee(AbstractBaseUser):
firstName = models.CharField(verbose_name = "firstName", max_length=20)
name = models.CharField(verbose_name = "name", max_length=20)
registrationNumber = models.CharField(verbose_name="registrationNumber", max_length=20, primary_key=True)
sectorCode = models.ForeignKey(Sector, on_delete=models.CASCADE)
USERNAME_FIELD="registrationNumber"
REQUIRED_FIELDS = ["name", "firstName", "sectorCode"]
objects = MyUserManager()
class Meta: db_table = "Employee"
If you know the sector exists, you can work with:
class MyUserManager(BaseUserManager):
def create_user(
self, registrationNumber, firstName, name, sectorCode, password=None
):
if not firstName:
raise ValueError("firstName required")
if not name:
raise ValueError("name required")
if not registrationNumber:
raise ValueError("registrationNumber required")
if not sectorCode:
raise ValueError("sectorCode required")
user = self.model(
firstName=firstName,
name=name,
registrationNumber=registrationNumber,
sectorCode_id=sectorCode,
)
user.set_password(password)
user.save()
return user
# …
If you want to create a Sector in case that one is missing, you can use:
class MyUserManager(BaseUserManager):
def create_user(
self, registrationNumber, firstName, name, sectorCode, password=None
):
if not firstName:
raise ValueError("firstName required")
if not name:
raise ValueError("name required")
if not registrationNumber:
raise ValueError("registrationNumber required")
if not sectorCode:
raise ValueError("sectorCode required")
sector, __ = Sector.objects.get_or_create(
sectorCode=sectorCode, defaults={'nameSector': sectorCode}
)
user = self.model(
firstName=firstName,
name=name,
registrationNumber=registrationNumber,
sectorCode=sector,
)
user.set_password(password)
user.save()
return user
# …
Code1 will however not be valid, since the sector code has a maximum length of three characters.
Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: first_name instead of firstName.

Django-invitations, Django-Allauth: pass model field data from custom invitation to (custom) user object

I'm combining django-invitations with django-allauth for user invitation and signup.
I'd like the Administrator (when creating an invitation through the Django Admin) to provide extra data (here a foreign key to Patient object). This is archieved by adding an extra field to the (custom) invitation model:
class PatientInvitation (AbstractBaseInvitation):
email = models.EmailField(unique=True, verbose_name=_('e-mail address'),
max_length=app_settings.EMAIL_MAX_LENGTH)
created = models.DateTimeField(verbose_name=_('created'),
default=timezone.now)
patient = models.ForeignKey(Patient, blank=True, null=True, on_delete=models.CASCADE)
#classmethod
def create(cls, email, inviter=None, patient=None, **kwargs):
key = get_random_string(64).lower()
instance = cls._default_manager.create(
email=email,
key=key,
inviter=inviter,
patient=patient,
**kwargs)
return instance
def key_expired(self):
expiration_date = (
self.sent + datetime.timedelta(
days=app_settings.INVITATION_EXPIRY))
return expiration_date <= timezone.now()
def send_invitation(self, request, **kwargs):
current_site = kwargs.pop('site', Site.objects.get_current())
invite_url = reverse('invitations:accept-invite',
args=[self.key])
invite_url = request.build_absolute_uri(invite_url)
ctx = kwargs
ctx.update({
'invite_url': invite_url,
'site_name': current_site.name,
'email': self.email,
'key': self.key,
'inviter': self.inviter,
})
When the invited user signs up, I would like this data to end up in the Custom user model:
class customUser(AbstractUser):
username_validator = MyValidator()
is_patient = models.BooleanField(default=False)
patient = models.ForeignKey(Patient, null=True, blank=True, on_delete=models.CASCADE)
username = models.CharField(
_('username'),
max_length=150,
unique=True,
)
I've looked into the signals to pass the data, but couldn't find how exactly to do this.
Another option seems to add the PK of the foreign key to a hidden field on the signup form (this seems unsafe though).
I'm a bit stuck on this one, so if anyone could point me in the right direction, It would be greatly appreciated :)
Regards,
Joris
Use allauth's signals instead; you'll have much more options and you can still accomplish exactly what you want.
I would create signals.py in your app directory.
Register your signals file under your apps.py like so:
from django.apps import AppConfig
class AccountsConfig(AppConfig):
name = 'app_name'
def ready(self): ###<-----------
import app_name.signals ###<-----------
Use the user_signed_up signal to update the user with the invitation's data:
signals.py
from allauth.account.signals import user_signed_up
from invitations.utils import get_invitation_model
def user_signed_up(request, user, **kwargs):
try:
Invitation = get_invitation_model() ### Get the Invitation model
invite = Invitation.objects.get(email=user.email) ### Grab the Invitation instance
user.patient = invite.patient ### Pass your invitation's patient to the related user
user.save()
except Invitation.DoesNotExist:
print("this was probably not an invited user.")

Django allauth Serialization error custom User model with TimeZoneField

My custom User model have a TimeZoneField:
from timezone_field import TimeZoneField
class User(AbstractBaseUser, PermissionsMixin):
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
email = models.EmailField(_('email address'), unique=True, blank=False, null=False)
username = models.CharField(_('user name'), max_length=128, unique=True, blank=False, null=False)
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)
language = models.CharField(_('Language'), choices=settings.LANGUAGES, default=settings.ENGLISH, max_length=2)
timezone = TimeZoneField(verbose_name=_('Timezone'), default='Europe/London')
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
I use django-allauth for registration by Google accounts. When existing user (registered by google email before, not Google Account) trying login by Google Account we have error:
<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD> is not JSON serializable
Traceback:
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/providers/oauth2/views.py" in view
55. return self.dispatch(request, *args, **kwargs)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/providers/oauth2/views.py" in dispatch
125. return complete_social_login(request, login)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/helpers.py" in complete_social_login
142. return _complete_social_login(request, sociallogin)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/helpers.py" in _complete_social_login
158. ret = _process_signup(request, sociallogin)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/helpers.py" in _process_signup
25. request.session['socialaccount_sociallogin'] = sociallogin.serialize()
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/socialaccount/models.py" in serialize
189. user=serialize_instance(self.user),
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/allauth/utils.py" in serialize_instance
194. return json.loads(json.dumps(data, cls=DjangoJSONEncoder))
File "/usr/lib/python3.4/json/__init__.py" in dumps
237. **kw).encode(obj)
File "/usr/lib/python3.4/json/encoder.py" in encode
192. chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.4/json/encoder.py" in iterencode
250. return _iterencode(o, 0)
File "/webapps/myproject/tmp/venv/lib/python3.4/site-packages/django/core/serializers/json.py" in default
115. return super(DjangoJSONEncoder, self).default(o)
File "/usr/lib/python3.4/json/encoder.py" in default
173. raise TypeError(repr(o) + " is not JSON serializable")
Exception Type: TypeError at /accounts/google/login/callback/
Exception Value: <DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD> is not JSON serializable
What are some ways to serialize a custom field in allauth?
My solution is replace default DefaultSocialAccountAdapter and extension serialize_instance (from allauth.utils) for serializing TimeZoneField. Don't forget set custom adapret in project settings:
SOCIALACCOUNT_ADAPTER = 'myapp.adapter.MySocialAccountAdapter'
Also I replaced pre_social_login for association Social account with Direct account (registered by email) (Thanks elssar for his example: https://stackoverflow.com/a/19443127/4012716)
myapp.adapter.py:
import json
import base64
import logging
from django.db.models import FieldDoesNotExist, FileField
from django.db.models.fields import (BinaryField)
from django.utils import six
from django.core.serializers.json import DjangoJSONEncoder
from django.shortcuts import HttpResponse
try:
from django.utils.encoding import force_text
except ImportError:
from django.utils.encoding import force_unicode as force_text
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.account.adapter import DefaultAccountAdapter
from allauth.utils import SERIALIZED_DB_FIELD_PREFIX
from allauth.exceptions import ImmediateHttpResponse
from timezone_field import TimeZoneField
from accounts.models import User
logger = logging.getLogger("django")
def my_serialize_instance(instance):
"""Instance serializer supported of serialization of TimeZoneField.
:param instance:
:return:
"""
data = {}
for k, v in instance.__dict__.items():
if k.startswith('_') or callable(v):
continue
try:
field = instance._meta.get_field(k)
if isinstance(field, BinaryField):
v = force_text(base64.b64encode(v))
elif isinstance(field, FileField):
if not isinstance(v, six.string_types):
v = v.name
elif isinstance(field, TimeZoneField):
v = six.text_type(v.zone)
# Check if the field is serializable. If not, we'll fall back
# to serializing the DB values which should cover most use cases.
try:
json.dumps(v, cls=DjangoJSONEncoder)
except TypeError:
v = field.get_prep_value(v)
k = SERIALIZED_DB_FIELD_PREFIX + k
except FieldDoesNotExist:
pass
data[k] = v
return json.loads(json.dumps(data, cls=DjangoJSONEncoder))
class MySocialAccountAdapter(DefaultSocialAccountAdapter):
"""Custom SocialAccountAdapter for django-allauth.
Replaced standard behavior for serialization of TimeZoneField.
Need set it in project settings:
SOCIALACCOUNT_ADAPTER = 'myapp.adapter.MySocialAccountAdapter'
"""
def __init__(self, request=None):
super(MySocialAccountAdapter, self).__init__(request=request)
def pre_social_login(self, request, sociallogin):
# This isn't tested, but should work
try:
emails = [email.email for email in sociallogin.email_addresses]
user = User.objects.get(email__in=emails)
sociallogin.connect(request, user)
raise ImmediateHttpResponse(response=HttpResponse())
except User.DoesNotExist:
pass
except Exception as ex:
logger.error(ex)
def serialize_instance(self, instance):
return my_serialize_instance(instance)

python-social not saving response to custom model

Ive been running into a number of problem in relation to using django's custom model. This one in particular is not raising any errors. For some reason after authenticating via steam and returning to the landing page the database tables for both steamuser_user (custom user) and social_auth_usersocialauth are empty. Nothing is being saved, no errors are being displayed etc.
My custom model which is quite similar to the one on django docs official page is as follows:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import BaseUserManager
# Create your models here.
class UserManager(BaseUserManager):
def create_user(self, steamid, username, password=None):
if not steamid:
msg = 'User has no Steam ID set'
raise ValueError(msg)
if not username:
msg = 'User has no name set'
raise ValueError(msg)
user = self.model(steamid=steamid,
username=username)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, steamid, username, password):
super_user = self.create_user(steamid=steamid,
username=username,
password=password)
super_user.is_staff = True
super_user.is_admin = True
super_user.is_mod = True
super_user.save(using=self._db)
return super_user
class User(AbstractBaseUser):
steamid = models.CharField(max_length=20, unique=True)
username = models.CharField(max_length=80)
email = models.EmailField(null=True,blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_mod = models.BooleanField(default=False)
date_joined = models.DateTimeField(auto_now_add=True)
reputation = models.IntegerField(max_length=6, default=0)
USERNAME_FIELD = 'steamid'
objects = UserManager()
def __unicode__(self):
return self.username
def get_full_name(self):
return self.steamid
def get_short_name(self):
return self.username
The settings I've used are as follows:
SOCIAL_AUTH_USER_MODEL = 'steamuser.User'
AUTH_USER_MODEL = 'steamuser.User'
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
'social.apps.django_app.context_processors.backends',
'social.apps.django_app.context_processors.login_redirect',
)
AUTHENTICATION_BACKENDS = (
'social.backends.steam.SteamOpenId',
'django.contrib.auth.backends.ModelBackend',
)
#Steam OpenAuth
SOCIAL_AUTH_STEAM_API_KEY = 'B1D7C629D093D4B72577F2F11DE4EBE2'
LOGIN_URL = '/'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'
SOCIAL_AUTH_ENABLED_BACKENDS = (
'steam',
)
Any help would be appreciated!
EDIT
Backends steam.py
def get_user_details(self, response):
player = self.get_json(USER_INFO, params={
'key': self.setting('API_KEY'),
'steamids': self._user_id(response)
})
if len(player['response']['players']) > 0:
player = player['response']['players'][0]
details = {'steamid': player.get('steamid'),
'username': player.get('personaname'),
}
else:
details = {}
return details
EDIT 2
Well despite my logical reasoning, I just gave up and created a custom pipeline to create the new steam user as follows:
from django.contrib.auth import get_user_model
def create_steamuser(details, user=None, *args, **kwargs):
if user:
return {'is_new': False}
if not details:
return
try:
steam_user = get_user_model().objects.get(steamid=details['steamid'])
except steam_user.DoesNotExist:
get_user_model().objects.create_user(details['steamid'], details['username'])
return {
'is_new': True,
}
Now I still have the problem where social_user is not being created. I've set the social user model to use my new custom model but there must be something that I am missing.
python-social-auth won't be able to pass the steamid and date_joined parameters to your custom create_user() method in the manager. To make that possible you have three options:
Set =None to those parameters and set some default vaules for them
Override the default create_user pipeline and pass the extra parameters.
Add a custom pipeline function before create_user and fill details with steamid and date_joined, then define SOCIAL_AUTH_STEAM_USER_FIELDS = ('username', 'email', 'steamid', 'date_joined').

Django authentication - modifying existing user on signup

I am building a photo sharing site with django where users are allowed to create groups to share photos. I have problems creating a proper user data model/logic which would cover all my requirements.
The basic requirements are:
User A is allowed to create a group where he can add another users (User B)
If the user B which has to be added to the group already exists then we will use this existing user B to be added to manytomany field of the group model representing the group
If the user B doesn't exist we will create a sort of "dummy" user. Setting the user_active to false. This is because the user B doesn't have set any sort of verification or password yet.
Now if the new added user B wants to be registered to the site, instead of creating a new user I would like to change the already existing user with the provided data from the signup form.
I would like to mention that I plan to use also the django-allauth for the social accounts users.
My question (considering the Django 1.5) is what would be the preferred way how to make this working:
Is this is something I should create my own User Manager or should I look into authentication backends ? I am really lost at this point.
Below is the diagram which represent both of the scenarios, signing up and adding of the user to the group:
http://i821.photobucket.com/albums/zz136/jorge_sanchez4/f79934d4-d0a4-4862-ab8b-7e1d09cd5642_zps06ec08f3.jpg
UPDATE:
So I tried following, created the custom user model where in the __new__ method I am returning the relevant object if it already exists and the is_active is set to False. Below is the both UserManager and user model:
class GruppuUserManager(BaseUserManager):
def create_user(self, username, email=None, password=None, phonenumber=None, **extra_fields):
now = timezone.now()
if not username:
raise ValueError('The given username must be set')
if not phonenumber:
raise ValueError('The given phonenumber must be set')
''' now lookup the user if it exists and is_active is set
then it is duplicate, otherwise return the user
and set the is_active to true '''
email = self.normalize_email(email)
if GruppUser.objects.filter(phonenumber__exact=phonenumber).exists():
if GruppUser.objects.filter(phonenumber__exact=phonenumber).values('is_active'):
''' duplicate - raise error '''
raise ValueError('The user is duplicate ')
else:
''' get the subscriber and set all the values '''
user = GruppUser.objects.filter(phonenumber__exact=phonenumber)
user.set_password(password)
user.is_active=True
if email:
user.email = email
user.save(using=self._db)
return user
user = self.model(username=username, email=email,
is_staff=False, is_active=True, is_superuser=False,
last_login=now, date_joined=now, phonenumber=phonenumber, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, email=None, password=None, phonenumber=None, **extra_fields):
u = self.create_user(username, email, password, phonenumber, **extra_fields)
u.is_staff = True
u.is_active = True
u.is_superuser = True
u.save(using=self._db)
return u
class GruppUser(AbstractBaseUser, PermissionsMixin):
''' django 1.5 - creating custom user model '''
id = models.AutoField(primary_key=True)
username = models.CharField(_('username'), max_length=30, unique=True,
help_text=_('Required. 30 characters or fewer. Letters, numbers and '
'#/./+/-/_ characters'),
validators=[
validators.RegexValidator(re.compile('^[\w.#+-]+$'), _('Enter a valid username.'), 'invalid')
])
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('email address'), blank=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)
phonenumber = models.CharField(max_length=10)
#following = models.ManyToManyField(Stream,blank=True,null=True)
blocked_con = models.ManyToManyField(Blocked_Content,blank=True,null=True)
mmsemail = models.EmailField(_('email address'), blank=True)
smsemail = models.EmailField(_('email address'), blank=True)
verified = models.BooleanField(_('verified'), default=False,
help_text=_('Defines if the user has been verified'))
objects = GruppuUserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['phonenumber']
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
def __init__(self,phone=None,*args, **kwargs):
''' save the phone number '''
super(GruppUser,self).__init__(*args, **kwargs)
self.phonetocheck = phone
#staticmethod
def __new__(cls,phone=None,*args, **kwargs):
''' lookup for the same user '''
if GruppUser.objects.filter(phonenumber__exact=phone).exists():
if self.objects.filter(phonenumber__exact=phone).values('is_active'):
''' duplicate - raise error '''
raise ValueError('The user is duplicate')
else:
''' get the subscriber and set all the values '''
user = self.objects.filter(phonenumber__exact=phone)
user.is_active = True
return user
return super(GruppUser,cls).__new__(cls,*args, **kwargs)
def get_full_name(self):
"""
Returns the first_name plus the last_name, with a space in between.
"""
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
"Returns the short name for the user."
return self.first_name
def email_user(self, subject, message, from_email=None):
"""
Sends an email to this User.
"""
send_mail(subject, message, from_email, [self.email])
Anyway the strange issue I am having right now is that I can't connect to the admin site which is giving me following error:
I have traced the django and it seems that the query set is somehow shifted to the left:
(Pdb) context[self.user].phonenumber
u''
(Pdb) context[self.user].date_joined
u'9135261969'
(Pdb) context[self.user].is_active
datetime.datetime(2013, 9, 8, 20, 47, 30, tzinfo=<UTC>)
But the data in mysql is correct:
mysql> select is_active from demo_app_gruppuser;
+-----------+
| is_active |
+-----------+
| 1 |
+-----------+
1 row in set (0.00 sec)
mysql> select phonenumber from demo_app_gruppuser;
+-------------+
| phonenumber |
+-------------+
| 9135261969 |
+-------------+
1 row in set (0.00 sec)
mysql> select date_joined from demo_app_gruppuser;
+---------------------+
| date_joined |
+---------------------+
| 2013-09-08 20:47:30 |
+---------------------+
1 row in set (0.00 sec)
Here is the backtrace when trying to login to the admin:
20. context[self.varname] = LogEntry.objects.filter(user__id__exact=user_id).select_related('content_type', 'user')[:int(self.limit)]
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/manager.py" in filter
155. return self.get_query_set().filter(*args, **kwargs)
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/query.py" in filter
667. return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/query.py" in _filter_or_exclude
685. clone.query.add_q(Q(*args, **kwargs))
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/sql/query.py" in add_q
1259. can_reuse=used_aliases, force_having=force_having)
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/sql/query.py" in add_filter
1190. connector)
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/sql/where.py" in add
71. value = obj.prepare(lookup_type, value)
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/sql/where.py" in prepare
339. return self.field.get_prep_lookup(lookup_type, value)
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/fields/__init__.py" in get_prep_lookup
322. return self.get_prep_value(value)
File "/usr/site/gruppe/lib/python2.7/site-packages/django/db/models/fields/__init__.py" in get_prep_value
555. return int(value)
Exception Type: ValueError at /admin/
Exception Value: invalid literal for int() with base 10: 'root'
Also in pdb is interesting that self.user.id which should be in this case 1 is returning "root" back. Seems that somehow django messed up what my pk are in this model even when I specified it in the model :
id = models.AutoField(primary_key=True)
Turns out that using __new__ method on Django model is not good idea, using the Model Manager create_user is working ok.