Quick (probably foolish) question. This is the flow of my site: User logs in and is redirected to a custom admin page. On this admin page they have the ability to make a 'Profile'. I want to associate the Profile they create with their User data such that 1 User associates to 1 Profile.
For some reason the following isn't working (simply trying to associate
UserAdmin.Models
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
username = models.ForeignKey(User)
firstname = models.CharField(max_length=200)
lastname = models.CharField(max_length=200)
email = models.EmailField(max_length=200)
def __unicode__(self):
return self.username
UserAdmin.Views
def createprofile(request):
user = User.objects.get(id=1)
profile = Profile(username=user, firstname='Joe', lastname='Soe', email='Joe#Soe.com')
profile.save()
I keep getting: table useradmin_profile has no column named username_id
Any ideas? Appreciated.
EDIT:
Deleted my db and ran a fresh syncdb, changed to username = models.OneToOneField(User). Now I cam getting Cannot assign "u'superuser'": "Profile.username" must be a "User" instance.
UserAdmin.Models
from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User)
def __unicode__(self):
return self.user.get_full_name()
UserAdmin.Views
def createprofile(request):
user_ = User.objects.get(pk=1)
profile = Profile(user=user_)
profile.user.first_name = 'Joe'
profile.user.last_name = 'Soe'
profile.user.email = 'Joe#Soe.com'
profile.user.save()
profile.save()
You syncdb'ed the Profile model before you had a username ForeignKey field. Django will only create tables but will not alter them once they have been created. Here an answer listing your options:
https://stackoverflow.com/a/7693297/990224.
And you should think about renaming username to user.
Related
I'm trying to create my own User class called Customer which extends the AbstractUser model and has an additional field called address. When I register, I see the user has been created in Django admin and all the fields (username, first name, last name and email) are seen in the django admin screen but I see no value in the "address" field. How do I know if the address is being saved and how can I display it in the admin site?
Below is my code for the models.py
class Customer(AbstractUser):
username = models.CharField(unique=True, max_length=20)
deladdress = models.CharField(max_length=100)
views.py
def signupPage(request):
signForm = CreateCustomer()
if request.method=='POST':
signForm = CreateCustomer(request.POST)
if signForm.is_valid():
signForm.save()
return render(request, 'trial_app/signup.html', {'signForm':signForm})
forms.py
class CreateCustomer(UserCreationForm):
address = forms.CharField(widget=forms.Textarea)
class Meta:
model = Customer
fields = ['username','first_name','last_name','email','address','password1','password2']
def save(self, commit=True):
user = super(CreateCustomer, self).save(commit=False)
user.address = self.cleaned_data["address"]
if commit:
user.save()
return user
Here are some pictures that are the input to my html form and the value in the admin site
It seems like when you save a form in its save method you use
user.address = self.cleaned_data["address"], however, Customer model does not have address field, it has deladdress, so try to rename a field, or use user.deladdress in your save method of CreateCustomer form.
Im trying to register users hashing their passwords before add to database as follows
settings.py
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.MD5PasswordHasher',
)
Models.py
from django.contrib.auth.models import AbstractBaseUser
class Users(AbstractBaseUser):
name = models.CharField(max_length=200)
email = models.CharField(max_length=200)
password = models.CharField(max_length=255)
Views.py
name = form.cleaned_data.get('name')
email = form.cleaned_data.get('email')
password = form.cleaned_data.get('password')
date_joined = date.today()
if Users.objects.filter(email=email).exists() and Users.objects.filter(name=name).exists() :
messages.info(request, 'User already exists')
else:
Users.objects.create(name=name, email=email, password=set_password(password), date_joined=date_joined)
but when i actually trying to create the user i get Python : name 'set_password' is not defined
What is wrong? do i need to import something at Views.py?
You must use set_password() on a user instance, not when creating a user.
Try this:
user = Users.objects.create(first_name=name, email=email, date_joined=date_joined)
user.set_password(password)
user.save()
I can see you are extending the user model. I'd have a look at some articles for ways to do this, I recommend this article.
I'm trying to log users in with django authenticate. It returns nothing even when the email and password are correct. It just reloads the page and doesn't do anything. I have checked and the email and password I used are stored in the database, so the account exist but login doesn't do anything. I am using django 2.
Views.py
def signup(request):
if request.method == "POST":
firstname = request.POST.get('firstname')
lastname = request.POST.get('lastname')
email = request.POST.get('email')
password = request.POST.get('password')
passwordagain = request.POST.get('passwordagain')
areacode = request.POST.get('areacode')
number = request.POST.get('number')
userdetails = CustomUser(firstname=firstname,lastname=lastname,email=email,password=password, areacode=areacode, number=number)
userdetails.save()
return render(request, 'main/accountconfirmationpage.html')
else:
return render(request,'main/signup.html')
def login(request):
email=request.POST.get('email')
password=request.POST.get('password')
user = authenticate(request, email=email, password=password)
if user is not None:
if user.is_active:
login(request, user)
return render(request,'main/dashboard.html')
else:
return render(request, 'main/login.html')
from django.db import models
Models.py
# Create your models here.
class CustomUser(models.Model):
firstname = models.CharField(max_length=30)
lastname = models.CharField(max_length=30)
email = models.EmailField(max_length=30)
password = models.CharField(max_length=100)
areacode = models.CharField(max_length=4)
number = models.CharField(max_length=30)
I think the problem is with your signup. You are not storing password properly in signup view.
userdetails = CustomUser(firstname=firstname,lastname=lastname,email=email,password=password, areacode=areacode, number=number) # <-- Here
userdetails.save()
As you are not storing the password properly(currently it is being stored as plaintext rather than hashed), that is why authenticate function is not able to get the user.
So, you need to set password like this:
userdetails = CustomUser(firstname=firstname,lastname=lastname,email=email, areacode=areacode, number=number)
userdetails.set_password(password)
userdetails.save()
For more details, please check here on set_password function.
You need to extend the Django User Model like this:
Models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
#this will extend User model with your own model
class CustomUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
# all the other fields you mentioned except areacode and number
# are already in User model so don't need to add them here
areacode = models.CharField(max_length=4)
number = models.CharField(max_length=30)
# Below code will hook the create_custom_user and save_custom_user methods
# to the User model, whenever a save event occurs
#receiver(post_save, sender=User)
def create_custom_user(sender, instance, created, **kwargs):
if created:
CustomeUser.objects.create(user=instance)
#receiver(post_save, sender=User):
def save_custom_user(sender, instance, **kwargs):
instance.customeuser.save()
Now you can create the user with your CustomModel in views like this:
Views.py
from django.contrib.auth.models import User
def signup(request):
if request.method == "POST":
# I would suggest to use django forms
# instead of getting the values directly from request.POST
user = User(firstname=firstname, lastname=lastname, email=email)
user.customuser.areacode = areacode
user.customuser.number = number
user.set_password(password)
user.save()
# rest of the code
doc for forms in django
Also for login the user with email instead of username you need to write an authentication backend for that and register it in your settings.py take a look here
trying to create a model that has an artist and song and lets you know what user name typed it in.
so far I have in my models.py
from django.contrib.auth.models import User
class Song(models.Model):
uesrname = models.ForeignKey(User,on_delete=models.CASCADE)
artist = models.CharField(max_length=30)
song=models.CharField(max_length=30)
I added a form that works with user input data but the form lets me select one of all exciting Users and input artist, song
forms.py
class NewSong(forms.ModelForm):
class Meta:
model=Song
exclude = ['username']
how can I change it so I will have only my own loged in user in the form?
You can exclude username field as exclude = ['username'] on your forms.py file and set username to request.user on form's save method. For more information: selecting fields
Let's say you have a django model with a OneToOne / Unique ForeignKey relationship with a User, as show on the Django documentation on how to create a UserProfile.:
Now let's say you have a view method that takes a request you can get a user from. What is the best way to query for the profile associated with that user?
from django.contrib.auth.models import User
# sample user profile model associated with user
class UserProfile(models.Model):
likes_spam = models.BooleanField()
user = models.OneToOneField(User)
#view method
def forward_to_practice_home(request):
user = request.user
profile_for_user = #insert code here that would get the profile for that user
related_names are very helpful. If you change your user profile definition to:
class UserProfile(models.Model):
likes_spam = models.BooleanField()
user = models.OneToOneField(User, related_name='profile')
then you can use profile as follows:
def forward_to_practice_home(request):
user = request.user
profile_for_user = user.profile
UserProfile.objects.get(user=user)
You may use a special method called get_profile()
profile_for_user = user.get_profile()
Be reminded that you have to set the AUTH_PROFILE_MODULE in the settings.py
However, this is deprecated in Django 1.5 because it adds the support of user model customization