How to link two tables in django? - python

I use the built-in User model in django, but i want use some custom fields, i was create new model
class Profile(models.Model):
user = models.OneToOneField(User)
profile_img = models.ImageField(null=True)
def __str__(self):
return self.user.username
this is my custom model.
But when i create new user it doesn't display in admin(in profile table), i need to add user from admin panel, after adding it works fine. what i should to do to display Profile info of all users?
p.s. When i was create table profile and was try to select info from joined tabels, sql query wasn't return anything, but after adding existed user to Profile table sql query return all what i want

To create a new Profile object when a new user is created, you can use a pre_save receiver:
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(
user=instance
)
The created parameter is to check if the object has been created ( created=True ) or updated ( created=False )

I am not sure to understand what you want... If you want to manage profile in admin app you have to register it.
from django.contrib import admin
from myproject.myapp.models import Profile
class ProfileAdmin(admin.ModelAdmin):
pass
admin.site.register(Profile, ProfileAdmin)
Edit: you can use a signal to automatically create a profile when creating a user.
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from myproject.myapp.models import Profile
#receiver(post_save, sender=User)
def create_profile(sender, instance **kwargs):
Profile.objects.create(user=instance)
Note that sometime using signals may be hard to maintain. You can also use AbstractBaseUser. This is a classical issue, which is widely covered in a lot of posts.
One I particularly like: https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html

Related

Django add every user in foreign key model with default values

I have created a Django model with a foreign key from user, I want that all created user before be created in that table with a default value:
Models.py
from django.contrib.auth.models import User
class UserProfiles(models.Model):
myuser = models.OneToOneField(User, on_delete=models.CASCADE)
userstatus = models.CharField(default='active', max_length=20)
Can you help me that I can migrate this table and be created to all users who are registered before?
Try something like this:
post_save
from django.contrib.auth.models import User
from django.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=UserProfiles)
def create_user_profile(sender, instance, created, **kwargs):
if created is True:
UserProfiles(instance)
I recommend creating this function in your app folder under signals.py
I hope this is what you are looking for

Adding multiple signals to User model creates record in forst table but not the second

I am using the standard django.contrib.auth.models User model and have extended it to create a Profile model with a one to one relationship with User to hold the profile picture. The signal for this is working fine. I since added another model, Roles, which needs a regular foreign key to User as a user can have multiple roles. The latter gives consistent errors no matter how I try to configure it including giving the fields different related_name in case it was confused which was which as well as having the Role model with a relationship to Profile rather than User but no matter how I seem to tackle it, I can't get the signal to work.
relevant models.py file code is as follows:
models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
...
class Role(TimeStampedModel):
user = models.ForeignKey(User, on_delete=models.CASCADE)
role = models.IntegerField('Roles',choices=Roles.choices, default=0)
...
signals.py:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User
from core.models import Profile, Role
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
Role.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
instance.role.save()
The debug error I am getting is as follows:
AttributeError at /login/
'User' object has no attribute 'role'
Request Method: POST
Request URL: http://127.0.0.1:8000/login/
Django Version: 3.0.8
Exception Type: AttributeError
Exception Value:
'User' object has no attribute 'role'
Exception Location: C:\project\path\core\signals.py in save_profile, line 15
I expect it's something to do with setting up a separate signal rather than having them in the same def but haven't been able to crack it after trying numerous ways. Likely just a silly thing I'm missing and will be grateful for a nudge in the right direction.
Thanks for taking a look.
Simon
user have not role but roles, is the default related name in foreignkey
you can change this by foreignkey(... , related_name="your_name")
so you can't do this for 2 reason
#receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
instance.role.save()
instance not have role but roles
instance.roles is not object but a queryset/list of role models

How to extend the user model in django 1.9?

I've been searching around trying to figure this out, I want to add simple things to my Profile model like avatar, contact info, etc. However when following tutorials that I found online on how to do this, I am only met with errors.
This is what my model looks like (tracks/models.py):
from django.db import models
from django.core.exceptions import ValidationError
from django.core.files.images import get_image_dimensions
from django.contrib.auth.models import User
...
class Profile(models.Model):
def generate_user_folder_avatar(instance, filename):
return "uploads/users/%s/%s.png" % (instance.user, 'avatar')
user = models.OneToOneField(User)
avatar = models.ImageField(upload_to=generate_user_folder_avatar,validators=[is_square_png])
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
I've set the AUTH_PROFILE_MODULE = 'tracks.Profile' in settings.py but when I run my server I get this error:
NameError: name 'post_save' is not defined
Any idea what I am doing wrong here? I'm using Django 1.9 and Python 3
NameError: name 'post_save' is not defined
you should do the import:
from django.db.models.signals import post_save
note #1: you may be interested in the fact that Django provides more explicit and clear way to extend User model:
https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#extending-django-s-default-user
note #2: you probably want to connect signals not somewhere in models, but like that: https://stackoverflow.com/a/21612050/699864

Django: OneToOneField has no attribute model

I am trying to create profile system where my users django username will be their username on the site, and also allow them to create a bio. However when I try to migrate, I get this error:
AttributeError: 'OneToOneField' object has no attribute 'model'
Here is my models.py files:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True)
bio = models.TextField(null=True)
slug = models.SlugField(default=user)
def __unicode__(self):
return "%s's profile" % self.user
def create_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
# Signal while saving user
from django.db.models.signals import post_save
post_save.connect(create_profile, sender=User)
And here is my admin.py:
from django.contrib import admin
from profiles.models import UserProfile
class UserProfileAdmin(admin.ModelAdmin):
list_display = ["user"]
admin.site.register(UserProfile, UserProfileAdmin)
Anyone know what the problem is? Thanks.
Try without importing the User model from django.contrib.auth.
Remove (or comment out) the User import line, the signal binding, and switch to string based model specification of relation in OneToOneField. The example of string based relation specification can be found in the docs.
This looks like a circular dependency thing.
If you'd still get an error, try to remove stuff you don't need from INSTALLED_APPS.

column user_id is not unique, with Django UserProfiles

I'm trying to add some extra attributes to a user by way of a User Profile in Django (1.2.5, the version supplied in Ubuntu natty), but whenever I create a new user through the admin console, with one of the new attributes included (eg, 'phone'), I get a "column user_id is not unique" IntegrityError.
I see that other people have had this problem, and they seem to have solved it by adding a unique dispatch_uid to the userprofile creation signal, but that's not working for me:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User)
phone = models.CharField(max_length=40,blank=True,null=True)
def create_user_profile(sender, instance, **kwargs):
UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User, dispatch_uid="users-profilecreation-signal")
AUTH_PROFILE_MODULE is set to point at this class, in settings.py.
Anyone know what I'm doing wrong?
There are two attempts to create the same profile. One from the signal and one directly from the inlined admin form.
This question/answer covers it and a potential solution in more detail.
Perhaps check to see if this is a signal for creating a user. You may be seeing a race condition with a number of callbacks.
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.get_or_create(user=instance)

Categories

Resources