I want to autogenerate a username in django - django

I want to create my own username for users in django
from django.contrib.auth import get_user_model
from datetime import date
from django.dispatch import receiver
from django.db.models.signals import pre_save
from django.db import models
User = get_user_model()
# auto username
#receiver(pre_save, sender=User)
def set_username(sender, instance, created, **kwargs):
if created:
instance.username = 'User-' + str(date.year) + '-' + str(instance.id)
instance.save()
so I created this signals.py file and I added this signals file to the app.py file in the app context but still it is not making any progress can someone help me to generate an username while filling the form.

this worked for me,
from django.contrib.auth import get_user_model
from datetime import date
from django.dispatch import receiver
from django.db.models.signals import pre_save
from django.db import models
import time
User = get_user_model()
# auto username signal
#receiver(pre_save, sender=User)
def set_username(sender, instance, created, **kwargs):
if created:
currentYear = time. strftime("%Y")
instance.username = f'User-{currentYear}-{str(instance.id)}'
instance.save()
models.signals.pre_save.connect(set_username, sender=User)
but still, I get this after saving the object i can't load value to the input form. Enough for me.

Related

its showing a warring that sender is not accessed! and same with **kwargs and when I login as admin my profile page shows the details about the admin

"""I'm unable to access senders and **kwargs and this is my signals.py file and I guess is causing a bug that is when I login as admin its start showing admin details in my profile page too, please help me out as I'm new to Django"""
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
def save_profile(sender, instance,**kwargs):
instance.profile.save()
[![enter image description here][3]][3]
the below image is of apps.py here is its showing users.signals is not accessed
[3]: https://i.stack.imgur.com/JxE5m.png

Why User model has type string?

I have a view that returns data corresponded to the user, but when I try to find the User I get this error:
Type str has no object method
File views.py
from .models import Question, User
#api_view(['POST'])
#renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def answers_view(request, *args, **kwargs):
userstring = request.data["name"]
try:
user0 = User.objects.get(username=userstring)
except ObjectDoesNotExist:
user0 = "NotFound"
print("USER: ", user0, flush = True)
File models.py
from django.db import models
# Create your models here.
import random
from django.conf import settings
from django.db import models
from django.db.models import Q
User = settings.AUTH_USER_MODEL
The AUTH_USER_MODEL setting is a string, this is often used to refer to the user model, for example in a ForeignKey, the advantage of this is that at that moment, the user model does not have to be loaded (yet).
In order to get a reference to the model, you use the get_user_model() function [Django-doc]:
from .models import Question
from django.contrib.auth import get_user_model
#api_view(['POST'])
#renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def answers_view(request, *args, **kwargs):
userstring = request.data['name']
try:
user0 = get_user_model().objects.get(username=userstring)
except ObjectDoesNotExist:
user0 = 'NotFound'
print('USER: ', user0, flush=True)

How to access post from username only?

I am writing models and i want to access post from username directly in django views. Is it possible? the models.py file is as follows:-
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
from django.utils import timezone
#this is how profile of a sample user, say MAX looks like
class Profile(models.Model):
Follwers=models.IntegerField(default='0')
user=models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True)
bio=models.TextField(max_length=120,blank=True)
location=models.CharField(max_length=30,blank=True)
birth_date=models.DateField(null=True,blank=True)
verified=models.BooleanField(default=False)
ProfilePic=models.ImageField(upload_to='UserAvatar',blank=True,null=True)
def __str__(self):
return self.user.username
#receiver(post_save,sender=User)
def update_user_profile(sender,instance,created,**kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
class post(models.Model):
Profile=models.ForeignKey(Profile,on_delete=models.CASCADE)
Picture=models.ImageField(upload_to='PostMedia',blank=True,null=True)
DatePosted=models.DateTimeField(default=timezone.now)
Content=models.TextField(blank=True,null=True)
def __str__(self):
return self.Profile.user.username
You can add this to views,
def get_queryset(self):
return post.objects.filter(Profile__user__username=self.kwargs['username'])
Modify it according to your kwargs, username or pk.

How can i fetch data from django models(database) using celery(asynchronously) from previously existing data

tasks.py
import string
from django.contrib.auth.models import User
from django.utils.crypto import get_random_string
from celery import shared_task
#shared_task
def create_random_user_accounts(total):
for i in range(total):
username = 'user_{}'.format(get_random_string(10, string.ascii_letters))
email = '{}#example.com'.format(username)
password = get_random_string(50)
User.objects.create_user(username=username, email=email, password=password)
return '{} random users created with success!'.format(total)
views.py
from django.contrib.auth.models import User
from .tasks import create_random_user_accounts
from django.http import JsonResponse
def users(request):
obj = list(User.objects.values())
create_random_user_accounts.delay(20)
return JsonResponse(obj,safe=False)
here i am inserting some random datas to User model using celery
And it is working while fetching same data.
But, i want to fetch 'existing data' from database 'without inseting' them on same request.
Please share me some idea how can i do that.
Method #1 do the insert off a POST and then retrieve via a GET:
from django.contrib.auth.models import User
from .tasks import create_random_user_accounts
from django.http import JsonResponse
from django.views.generic import View
class UserView(View):
def get(self, request, *args, **kwargs):
obj = list(User.objects.values())
return JsonResponse(obj,safe=False)
def post(self, request, *args, **kwargs):
create_random_user_accounts.delay(20)
obj = list(User.objects.values())
return JsonResponse(obj,safe=False)
Method #2 is just to remove the call to create_random_user_accounts, since that is what is creating the accounts:
from django.contrib.auth.models import User
from .tasks import create_random_user_accounts
from django.http import JsonResponse
def users(request):
obj = list(User.objects.values())
# create_random_user_accounts.delay(20)
return JsonResponse(obj,safe=False)

Creating a extended user profile

I have an extended UserProfile model in django:
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
#other things in that profile
And a signals.py:
from registration.signals import user_registered
from models import UserProfile
from django.contrib.auth.models import User
def createUserProfile(sender, instance, **kwargs):
profile = users.models.UserProfile()
profile.setUser(sender)
profile.save()
user_registered.connect(createUserProfile, sender=User)
I make sure the signal gets registered by having this in my __init__.py:
import signals
So that should create me a new UserProfile for every user that registers, right? But it doesn't. I always get "UserProfile matching query does not exist" errors when I try to log in, which means that the database entry isn't there.
I should say that I use django-registration, which provides the user_registered signal.
The structure of the important apps for this is, that I have one application called "users", there I have: models.py, signals.py, urls.py and views.py (and some other things which shouldn't matter here). The UserProfile class is defined in models.py.
Update: I changed the signals.py to:
from django.db.models.signals import post_save
from models import UserProfile
from django.contrib.auth.models import User
def create_profile(sender, **kw):
user = kw["instance"]
if kw["created"]:
profile = UserProfile()
profile.user = user
profile.save()
post_save.connect(create_profile, sender=User)
But now I get a "IntegrityError":
"column user_id is not unique"
Edit 2:
I found it. Looks like somehow I registred the signal twice. The workaround for this is described here: http://code.djangoproject.com/wiki/Signals#Helppost_saveseemstobeemittedtwiceforeachsave
I had to add a dispatch_uid, now my signals.py looks like this and is working:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from models import UserProfile
from django.db import models
def create_profile(sender, **kw):
user = kw["instance"]
if kw["created"]:
profile = UserProfile(user=user)
profile.save()
post_save.connect(create_profile, sender=User, dispatch_uid="users-profilecreation-signal")
You can implement it using post_save on the user:
from django.db.models.signals import post_save
from models import UserProfile
from django.contrib.auth.models import User
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
profile = users.models.UserProfile()
profile.setUser(sender)
profile.save()
post_save.connect(create_profile, sender=User)
Edit:
Another possible solution, which is tested and works (I'm using it on my site):
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
up = UserProfile(user=user, stuff=1, thing=2)
up.save()
post_save.connect(create_profile, sender=User)
You can get the extended profile to be created when first accessed for each user instead:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
additional_info_field = models.CharField(max_length=50)
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
then use
from django.contrib.auth.models import User
user = User.objects.get(pk=1)
user.profile.additional_info_field
ref: http://www.codekoala.com/blog/2009/quick-django-tip-user-profiles/
This helped me: primary_key=True
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True, primary_key=True, related_name="user")
phone = models.CharField(('phone'),max_length=30, blank=False, null=True)
user_building = models.ManyToManyField(Building, blank=True)
added_by = models.ForeignKey(User, blank=True, null=True, related_name="added")
When you call profile.setUser(), I think you want to pass instance rather than sender as the parameter.
From the documentation of the user_registered signal, sender refers to the User class; instance is the actual user object that was registered.
According to my latest research, creating a separate file, e.g., singals.py, does not work.
You'd better connect 'create_profile' to 'post_save' in your models.py directly, otherwise this piece of code won't be executed since it's in a separate file and no one imports it.
My final code for your reference:
# models.py
# Here goes the definition of class UserProfile.
class UserProfile(models.Model):
...
# Use signal to automatically create user profile on user creation.
# Another implementation:
# def create_user_profile(sender, **kwargs):
# user = kwargs["instance"]
# if kwargs["created"]:
# ...
def create_user_profile(sender, instance, created, **kwargs):
"""
:param sender: Class User.
:param instance: The user instance.
"""
if created:
# Seems the following also works:
# UserProfile.objects.create(user=instance)
# TODO: Which is correct or better?
profile = UserProfile(user=instance)
profile.save()
post_save.connect(create_user_profile,
sender=User,
dispatch_uid="users-profilecreation-signal")
Update for 2018:
This question has collected a lot of views, maybe it is time for an update.
This is the latest version for latest Django.
from django.dispatch import receiver
from django.db.models.signals import post_save
from django.conf import settings
from models import UserProfile
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_user_profile(sender, instance=None, created=False, **kwargs):
if created:
UserProfile.objects.create(user=instance)