Django 1.5 Custom User Model unknown column - django

I am using Django 1.5s Custom User Model. I want to let a user type their username in - and be logged in. NO PASSWORD (for testing anyway). My User Model doesnt have a password. But when i try to login to admin I get the following error:
OperationalError(1054, "Unknown column 'hrms.password' in 'field list'"
It seems to be trying to execute this query in the authenticate() method.
SELECT `myusers`.`password`, `myusers`.`last_login`, `myusers`.`id`, `myusers`.`user`, `myusers`.`name`, `myusers`.`firstname`, `myusers`.`lastname`, `myusers`.`organisation`, `myusers`.`unit`, `myusers`.`grade`, `myusers`.`email`, `myusers`.`position`, `myusers`.`manager` FROM `myusers` WHERE `myusers`.`user` = 'warrenm' "
I do not have the fields password, last_login - I dont know why its trying to get them.
Below is my code.
My Backend (auth.py)
from epmds.application.models import AuthUser
class MyBackend(object):
def get_user(self, user_id):
# get a user from the user_id
try:
return AuthUser.objects.get(pk=user_id)
except AuthUser.DoesNotExist:
return None
def authenticate(self, username=None, password=None):
# check the username/password and return a user
user = AuthUser.objects.get(user=username)
return user
MY Model
class AuthUser(AbstractBaseUser):
id = models.CharField(primary_key=True, max_length=15)
user = models.CharField('username', max_length=20, unique=True)
name = models.CharField(max_length=100)
firstname = models.CharField(max_length=100)
lastname = models.CharField(max_length=100)
organisation = models.CharField(max_length=100)
email = models.CharField(max_length=50, blank=True, null=True)
USERNAME_FIELD = 'user'
def get_full_name(self):
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
return self.first_name
class Meta:
ordering = ('lastname', 'firstname')
managed = False
db_table = 'myusers'

password is part of AbstractBaseUser so it should be added in your AuthUser model as well in table.
As you have managed=False for this model, you need to add that explicitly.

Related

django add object with the current user

I'm trying to create a todoapp with google login to create personal todolist for each users.
here's views.py
from django.contrib.auth.decorators import login_required
#login_required
def todoView(request):
all_todo_items = Todoitem.objects.filter(userid=request.user.id)
return render(request, 'todoapp/home.html', {'all_items': all_todo_items})
def addTodo(request):
add_new_item = Todoitem(content=request.POST['content'])
add_new_item.save()
return HttpResponseRedirect('/home/')
this is my code before without users but when there's currently login user it's throwing this error
null value in column "id" violates not-null constraint / DETAIL: Failing row contains (null, sampletodo,null). I believe the third column which is null is the userid and first column null is auto increment id since I set it to id SERIAL primary key in todoitem table
I'm 100% sure i need to add something #addTodo views.py, I just dont know how to add todolist with the current user
EDIT here's my models.py
class Todoitem(models.Model):
content = models.CharField(max_length=100)
userid = models.ForeignKey(AuthUser, models.DO_NOTHING,
db_column='userid')
class Meta:
managed = False
db_table = 'todoitem'
class AuthUser(models.Model):
password = models.CharField(max_length=128)
last_login = models.DateTimeField(blank=True, null=True)
is_superuser = models.BooleanField()
username = models.CharField(unique=True, max_length=150)
soon...
class Meta:
managed = False
db_table = 'auth_user'
Just pass the current user the same way you did in todoView. The request object has a reference to the current user through request.user. But you need to specify the user object, not user.id
#login_required
def todoView(request):
all_todo_items = Todoitem.objects.filter(userid=request.user) # changed to request.user
return render(request, 'todoapp/home.html', {'all_items': all_todo_items})
def addTodo(request):
add_new_item = Todoitem(content=request.POST['content'], userid=request.user)
add_new_item.save()
return HttpResponseRedirect('/home/')
You should use a good user model to be able to use request.user.
Try a model like this:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
password = models.CharField(max_length=128)
last_login = models.DateTimeField(blank=True, null=True)
is_superuser = models.BooleanField()
username = models.CharField(unique=True, max_length=150)
then in your views you can do this
def addTodo(request):
add_new_item = Todoitem(content=request.POST['content'], userid=request.user)
def todoView(request):
all_todo_items = Todoitem.objects.filter(userid=request.user) # changed to request.user
return render(request, 'todoapp/home.html', {'all_items': all_todo_items})

Password Confirmation error not displayed in django forms

I tried to compare password and confirmpassword. If i enter different password it does not raise error and redirects to loginpage.
models.py
class reg1(models.Model):
name=models.CharField(max_length=100)
city=models.CharField(max_length=100)
email=models.CharField(max_length=100)
username=models.CharField(max_length=100)
password=models.CharField(max_length=100)
cpassword=models.CharField(max_length=100)
class Meta:
db_table='reg1'
forms.py
class regform(forms.Form):
name = forms.CharField(max_length=100)
city = forms.CharField(max_length=100)
email = forms.CharField(max_length=100)
username = forms.CharField(max_length=100)
password = forms.CharField(max_length=100)
cpassword=forms.CharField(max_length=100)
def clean_password(self):
if self.data['password'] != self.data['cpassword']:
raise forms.Error('Passwords are not the same')
return self.data['password']
views.py
if myregform.is_valid():
name1 = myregform.cleaned_data['name']
city1 = myregform.cleaned_data['city']
email = myregform.cleaned_data['email']
username1 = myregform.cleaned_data['username']
password1 = myregform.cleaned_data['password']
password2=myregform.cleaned_data['cpassword']
a=reg1(name=name1,city=city1,email=email,
username=username1,password=password1,cpassword=password2)
a.save()
I expect the output as i enter a different password it will show password not matching error
I am using pycharm software and django framework with sqlite3 database.
Use a ModelForm to save yourself a bunch of typing.
You need to use clean() to validate data that relates to other fields.
You need to raise ValidationErrors.
class reg1(models.Model):
name = models.CharField(max_length=100)
city = models.CharField(max_length=100)
email = models.CharField(max_length=100)
username = models.CharField(max_length=100)
password = models.CharField(max_length=100)
cpassword = models.CharField(max_length=100)
class Meta:
db_table = "reg1"
class regform(forms.ModelForm):
class Meta:
model = reg1
exclude = ()
def clean(self, cleaned_data):
if cleaned_data["password"] != cleaned_data["cpassword"]:
raise forms.ValidationError("Passwords are not the same")
return cleaned_data
# ...
if myregform.is_valid():
a = myregform.save()

Why RelatedObjectDoesNotExist comes even after successful migration in pythonanywhere?

I know similar question asked, but in my case am getting RelatedObjectDoesNotExist after deployment to pythonanywhere.com.
"RelatedObjectDoesNotExist: User has no eisfiles."
However same codes works fine in local machine.
Model.py
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
class gwDashboard(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
htmlname = models.CharField(max_length=100)
def __str__(self): # __unicode__ on Python 2
return self.htmlname
class userInformation(models.Model):
user = models.ForeignKey(User)
DbName = models.CharField(max_length=200)
DbTable = models.CharField(max_length=200)
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=100)
class eisfiles(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
htmlname = models.CharField(max_length=100)
meterId = models.CharField(max_length=100)
esiid = models.CharField(max_length=100)
metermultiplier = models.CharField(max_length=100)
DbName = models.CharField(max_length=100,default='800WILCREST')
DbTable = models.CharField(max_length=100)
def __str__(self):
return self.htmlname
def __str__(self):
return self.DbName
class Member(models.Model):
ID = models.AutoField(primary_key=True)
FIRST_NAME = models.CharField('First name', max_length=50)
LAST_NAME = models.CharField('Last name', max_length=50)
# Using multi table inheritance - automaticly creates one to one field
class MemberDetail(Member):
DATE_OF_BIRTH = models.DateField('Date of birth')
EMAIL = models.EmailField('E-mail')
PHONE = models.CharField('Phone', max_length=15)
Views.py
def home(request):
userName = request.user
u = User.objects.get(username=userName);
DbName=u.eisfiles //THIS LINE OF CODE THROWS ERROR
try:
DbName=u.eisfiles //THIS LINE OF CODE THROWS ERROR
DbName=u.eisfiles.DbName
direct=''
return render_to_response(
'registration/result.html',
{ 'kWhHeatMap': kWhHeatMap, 'temHeatMap':temHeatMap,"histKwhChart":histKwhChart,'officeBuilding':officeBuilding},
)
except User.eisfiles.RelatedObjectDoesNotExist:
pass
return render_to_response(
'registration/result.html',
{ 'kWhHeatMap': "", 'temHeatMap':"","histKwhChart":"",'officeBuilding':""},
)
# except User.AttributeError:
# return HttpResponse('something went wrong!! try again')
finally:
pass
You may want to check if the user you're attempting to retrieve actually exists.
userName = request.user # ??? This is the user object not the username
u = User.objects.get(username=userName)
There appears to be a problem with your query.Try this instead:
user = request.user
u = User.objects.get(id=user.id)
DbName = u.eisfiles.DbName

How to create user profile with django-registration?

In django 1.7 I use django-registration to handle user registration and I'd like to automatically create a UserProfile instance for each newly registered user.
So in models I have:
class UserProfile(models.Model):
username = models.OneToOneField(User)
name = models.CharField(max_length=30)
occupation = models.CharField(max_length=50)
city = models.CharField(max_length=30)
#models.permalink
def get_absolute_url(self):
return ('view_pirate', None, {'username': self.account.user})
def __unicode__(self):
return unicode(self.username)
#**this line is supposed to create user profile****
User.profile = property(lambda u:UserProfile.objects.get_or_create(username=u)[0])
But when I check the database no new row in userprofile_userprofile is created after a new user registration. What is wrong here?
If the line is in wrong place, where should it be?

"Foreign Keys" across very separate databases in Django

I've writing a Django site that uses two different databases. One is the local, let's call it, "Django", database that stores all of the standard tables from a pretty standard install -- auth, sites, comments, etc. -- plus a few extra tables.
Most of the data, including users, comes from a database on another server, let's call it the "Legacy" database.
I'm looking for suggestions on clean, pythonic ways of connecting the two databases, particularly in regards to users.
I'm using a proxy model, which works great when I can explicitly use it, but I run into problems when I'm accessing the user object as a related object (for example, when using the built-in django comments system).
Here's what the code looks like:
models.py: (points to the Django database)
from django.db import models
from django.conf import settings
from django.contrib.auth.models import User as AuthUser, UserManager as AuthUserManager, AnonymousUser as AuthAnonymousUser
class UserPerson(models.Model):
user = models.OneToOneField(AuthUser, related_name="person")
person_id = models.PositiveIntegerField(verbose_name='Legacy ID')
def __unicode__(self):
return "%s" % self.get_person()
def get_person(self):
if not hasattr(self, '_person'):
from legacy_models import Person
from utils import get_person_model
Person = get_person_model() or Person
self._person = Person.objects.get(pk=self.person_id)
return self._person
person=property(get_person)
class UserManager(AuthUserManager):
def get_for_id(self, id):
return self.get(person__person_id=id)
def get_for_email(self, email):
try:
person = Person.objects.get(email=email)
return self.get_for_id(person.pk)
except Person.DoesNotExist:
return User.DoesNotExist
def create_user(self, username, email, password=None, *args, **kwargs):
user = super(UserManager,self).create_user(username, email, password, *args, **kwargs)
try:
person_id = Person.objects.get(email=email).pk
userperson, created = UserPerson.objects.get_or_create(user=user, person_id=person_id)
except Person.DoesNotExist:
pass
return user
class AnonymousUser(AuthAnonymousUser):
class Meta:
proxy = True
class User(AuthUser):
class Meta:
proxy=True
def get_profile(self):
"""
Returns the Person record from the legacy database
"""
if not hasattr(self, '_profile_cache'):
self._profile_cache = UserPerson.objects.get(user=self).person
return self._profile_cache
objects = UserManager()
legacy_models.py: (points to the "Legacy" database)
class Person(models.Model):
id = models.AutoField(primary_key=True, db_column='PeopleID') # Field name made lowercase.
code = models.CharField(max_length=40, blank=True, db_column="person_code", unique=True)
first_name = models.CharField(max_length=50, db_column='firstName', blank=True) # Field name made lowercase.
last_name = models.CharField(max_length=50, db_column='lastName', blank=True) # Field name made lowercase.
email = models.CharField(max_length=255, blank=True)
def __unicode__(self):
return "%s %s" % (self.first_name, self.last_name)
def get_user(self):
from models import User
if not hasattr(self,'_user'):
self._user = User.objects.get_for_id(self.pk)
return self._user
user = property(get_user)
class Meta:
db_table = u'People'
I've also whipped up my own middleware, so request.user is the proxy User object also.
The real problem is when I'm using something that has user as a related object, particularly in a template where I have even less control.
In the template:
{{ request.user.get_profile }}
{# this works and returns the related Person object for the user #}
{% for comment in comments %} {# retrieved using the built-in comments app %}
{{ comment.user.get_profile }}
{# this throws an error because AUTH_PROFILE_MODULE is not defined by design #}
{% endfor %}
Short of creating a wrapped version of the comments system which uses my proxy User model instead, is there anything else I can do?
Here's how I resolved it. I stopped using the User proxy altogether.
models.py:
from django.db import models
from legacy_models import Person
from django.contrib.auth.models import User
class UserPerson(models.Model):
user = models.OneToOneField(User, related_name="person")
person_id = models.PositiveIntegerField(verbose_name='PeopleID', help_text='ID in the Legacy Login system.')
def __unicode__(self):
return "%s" % self.get_person()
def get_person(self):
if not hasattr(self, '_person'):
self._person = Person.objects.get(pk=self.person_id)
return self._person
person=property(get_person)
class LegacyPersonQuerySet(models.query.QuerySet):
def get(self, *args, **kwargs):
person_id = UserPerson.objects.get(*args, **kwargs).person_id
return LegacyPerson.objects.get(pk=person_id)
class LegacyPersonManager(models.Manager):
def get_query_set(self, *args, **kwargs):
return LegacyPersonQuerySet(*args, **kwargs)
class LegacyPerson(Person):
objects = LegacyPersonManager()
class Meta:
proxy=True
and legacy_models.py:
class Person(models.Model):
id = models.AutoField(primary_key=True, db_column='PeopleID') # Field name made lowercase.
code = models.CharField(max_length=40, blank=True, db_column="person_code", unique=True)
first_name = models.CharField(max_length=50, db_column='firstName', blank=True) # Field name made lowercase.
last_name = models.CharField(max_length=50, db_column='lastName', blank=True) # Field name made lowercase.
email = models.CharField(max_length=255, blank=True)
def __unicode__(self):
return "%s %s" % (self.first_name, self.last_name)
def get_user(self):
from models import User
if not hasattr(self,'_user'):
self._user = User.objects.get_for_id(self.pk)
return self._user
def set_user(self, user=None):
self._user=user
user = property(get_user, set_user)
class Meta:
db_table = u'People'
Finally, in settings.py:
AUTH_PROFILE_MODULE = 'myauth.LegacyPerson'
This is a simpler solution, but at least it works! It does mean that whenever I want the legacy record I have to call user_profile, and it means that there's an additional query for each user record, but this is a fair trade-off because actually it isn't very likely that I will be doing a cross check that often.