I am following the tutorials
https://simpleisbetterthancomplex.com/tutorial/2017/02/18/how-to-create-user-sign-up-view.html
on making a simple user registration website.
The key model defined in model.py is
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
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
which creates the table profile in the database. My question is how do we append this table to include information like user's first/last name and email. I know those information is stored in auth_user, but it would nice to have everything on one table.
I am new to django platform. Any explanation or reference is greatly appreciated.
If you want to append first_name, last name, and email in Profile model then there is no need of this user = models.OneToOneField(User, on_delete=models.CASCADE)
so basically you can remove this line
and
append these field to the model like:
first_name = models.TextField(max_length=50, blank=True)
last_name = models.TextField(max_length=50, blank=True)
email = models.TextField(max_length=200, blank=True)
and run command: python manage.py makemigrations and then
python manage.py migrate
But i will not recomend you to do this.
I suggest you to use django auth user model because then you extra fetures of django very easily like maintaining sessions etc.
follow :- https://docs.djangoproject.com/en/2.0/intro/tutorial01/
Related
I am creating the super user through admin panel or command line, but it is not showing in the custom model in the database.
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
description = models.TextField(null=True)
profile_image = models.ImageField(null=True, blank=True)
def __str__(self):
return str(self.user)
class Following(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
following = models.CharField(max_length=30)
class Follower(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
follower = models.CharField(max_length=30)
Using OneToOnefield should create the user in the Profile model automatically but it is not happening. I am not sure what is wrong because in the previous project it was workiing fine. Also I have registered the models in admin.py.
To begin with, Here Profile and Seller model is created when a User model is created through Signals.What I want to do is When profile model is first created or updated,I want all the fields of Seller model to be same as all fields of Profile.Similarly when I first created Seller model,I also want all fields of Profile Model to be same as that of Seller model.But,I couldn't figure out how to do?
from typing import Tuple
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.db.models.fields import DecimalField
from django.dispatch import receiver
from django.db.models.signals import post_save
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True) #cascade is for deleting the customer
first_name = models.CharField(max_length=10, null=True)
second_name=models.CharField(max_length=10,null=True)
email = models.EmailField(max_length=70, null=True,blank=True)
#receiver(post_save, sender=User)
def create_profile(sender, instance,created,**kwargs):#Signal receivers must accept keyword arguments (**kwargs).
if created:
Profile.objects.create(user=instance)
...
#receiver(post_save, sender=Profile)
def create_seller(sender, instance,created,**kwargs):#Signal receivers must accept keyword arguments (**kwargs).
if created:
Seller.objects.create(user=instance)
class Seller(models.Model):
user = models.OneToOneField(Profile, on_delete=models.CASCADE, null=True, blank=True) #cascade is for deleting the customer
first_name = models.CharField(max_length=10, null=True)
second_name=models.CharField(max_length=10,null=True)
email = models.EmailField(max_length=70, null=True,blank=True)
...
If created=True it means a Profile object is created. otherwise if created=False it means that a Profile object has been updated.
When created=True you need to create a Seller object and when created=False you need to update a Seller object.
You can do this:
#receiver(post_save, sender=Profile)
def update_or_create_seller(sender, instance, created, **kwargs):
if created:
Seller.objects.create(
user=instance.user,
first_name=instance.first_name,
second_name=instance.second_name,
email=instance.email
)
else:
seller = instance.user.seller
seller.first_name = instance.first_name
seller.last_name = instance.second_name
seller.email = instance.email
seller.save()
Also notice that unless you define related_name in your OneToOneField, Django will use lowercased model name to access related object. So, instance.user.seller should work.
I am trying to migrate, and view the admin page. both makemigrations and migrate passed, yet when i go to the admin url it reads this: "django.db.utils.OperationalError: no such column: social_app_user.id"
And once i create an id field, it changes to "django.db.utils.OperationalError: no such column: social_app_user.password"
I was under the impression that the AbstractUser model included all the default user fields, not sure about the primary key, but regardless.
Please help, thanks!
Note: the 'id' field in this models.py file was added after i got the error.
from django.contrib.auth.models import AbstractUser, UserManager
from django.db import models
class User(AbstractUser):
is_verified = models.BooleanField(default=True)
id= models.AutoField(primary_key=True, null=False)
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
f"{self.username} {self.email}"
return
class main_feed(models.Model):
content= models.CharField(unique=True, max_length=255, default='', null=False)
poster = models.ForeignKey('User', related_name='author', on_delete=models.CASCADE, to_field='username')
likes = models.IntegerField(default=0, null=False)
favorites = models.IntegerField(default=0, null=False)
date_posted = models.DateTimeField(auto_now=True)
def __str__(self):
f"{self.content} {self.likes} {self.poster} {self.date_posted}"
return
It turns out I had to restart my entire application and run startapp again.
This time i added the user model and set up the settings and admin file BEFORE the very first migration. then everything works dandy. But I have no idea why this is the case, shouldnt the migration update and override the default user model?
anyways the question is answered now.
I'm creating a system in Django with admins(not superuser) and employees working under them. I've created admins registration and login using Django's built-in models. Now I have created custom model for employee's profile. The admin can only register the employee using his dashboard. This part has been done. Now I want to know that how to authenticate the employee's credentials so that the he/she can login to his/her own dashboard?
Note that the admin and superuser are different in this case. Admin cannot access superuser's panel.
The models are:
#ADMIN PROFILE
class AdminProfile(models.Model):
user=models.OneToOneField(User)
image = models.ImageField(upload_to='profile_pics/admin/', blank=True)
def __str__(self):
return self.user.username
#EMPLOYEE PROFILE
class EmployeeProfile(models.Model):
admin_name = models.ForeignKey(AdminProfile, on_delete = models.CASCADE, default=1)
emp_name = models.CharField(max_length=50)
email = models.EmailField(max_length=127, unique=True, null=False, blank=False)
password = models.CharField(max_length=20)
contact_no = models.PositiveIntegerField()
location = models.CharField(max_length=50)
image = models.ImageField(upload_to='profile_pics/employee/', blank=True)
def __str__(self):
return self.email
I want to have login validation for EmployeeProfile model.
I have already tried custom authentication using backends but it failed.
I'm new to Django and this is the part of my first project in Django.
Thank you in advance.
Edit: I solved this question by extending User model in the Employee profile as well.
I have the below in my models.py file:
class Film(models.Model):
title = models.CharField(max_length=200)
director = models.CharField(max_length=200)
description = models.CharField(max_length=200)
pub_date = models.DateField('date published')
class Comment(models.Model):
film = models.ForeignKey(Film, on_delete=models.CASCADE)
body = models.CharField(max_length=200)
When I logged into Django admin I added some films, and then added some comments, selecting which film object the comment related to. I then created a couple of users via the admin panel also.
I would like my relationships to be:
Film can have many comments / Comments belong to film
User can have many comments / Comments belong to user
I think, like with comments and films, I just need to define user as a foreign key to comment. I am struggling to do this. I am working through the Django tutorials but I can't see the tutorials covering how I can link other tables to the user.
I thought I would be able to do something like this:
user = models.ForeignKey(User, on_delete=models.CASCADE)
While importing User like this:
from django.contrib.auth.models import User
The result at the moment is if I keep user = models.ForeignKey(User, on_delete=models.CASCADE) I get err_connection_refused
Maybe have you changed your default user model in the settings?
Instead of using User directly with the the Foreign key, you should use user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) in your Comment Model, as follow
class Comment(models.Model):
film = models.ForeignKey(Film, on_delete=models.CASCADE)
body = models.CharField(max_length=200)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
You need to apply migrations to be able to add user to Comment,
python manage.py makemigrations
python manage.py migrate
if at the moment that you are applying migrations, shell shows a message telling You are trying to add a non-nullable field 'user' to comment without a default
You have 2 Options
Skip migrations and add a default value to the field in the models or set the attribute as nullable, whatever else that you need
ie
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
and apply migrations again
Or select a default value to the new field, should be an id of an existing user in databse
This is because django should populate existing records in database, if exist
Use "settings.AUTH_USER_MODEL".
So, import "settings" from "django.conf", then use "settings.AUTH_USER_MODEL" as shown below:
from django.db import models
from django.conf import settings # Here
class Comment(models.Model):
film = models.ForeignKey(Film, on_delete=models.CASCADE)
body = models.CharField(max_length=200)
# Here
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)