signals.py
#receiver(user_logged_in, sender=User)
def when_user_logs_in(sender, request, **kwargs):
print('user_logs_signal is called')
LoggedInUser.objects.get_or_create(user=kwargs.get('user'))
#receiver(user_logged_out, sender=User)
def when_user_logs_out(sender, request, **kwargs):
print('user logs out signal iscalled')
LoggedInUser.objects.get_or_create(user=kwargs.get('user')).delete()
models.py
class LoggedInUser(models.Model):
user = models.OneToOneField(User, related_name='logged_in_user', on_delete =models.CASCADE, null=True, blank=True)
session_key = models.CharField(max_length=32, null=True, blank=True)
def __str__(self):
return self.user.username
apps.py
class AccountsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "accounts"
def ready(self):
import accounts.signals
I have done anything that i found to solve signals now working but it didnt solve i have even added "accounts.apps.AccountsConfig" in my settings.py but still it not firing i am currently logged_in and using jwt based authentication , needs help
Related
why the signals don't work = create profile when user register
i wannt to know the is
----- settings
INSTALLED_APPS = [
'main',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
-----model
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
# Create your models here.
class profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
music = models.CharField(max_length=50)
skils = models.CharField(max_length=50)
search = models.CharField(max_length=50)
posts = models.CharField(max_length=50)
boi = models.TextField()
img = models.ImageField(upload_to="profile-img")
def __str__(self):
return self.user
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = profile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
why code dont work
why code dont work
You defined create_profile inside profile class, so it's not accessible to post_save.
class profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
music = models.CharField(max_length=50)
skils = models.CharField(max_length=50)
search = models.CharField(max_length=50)
posts = models.CharField(max_length=50)
boi = models.TextField()
img = models.ImageField(upload_to="profile-img")
def __str__(self):
return self.user
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = profile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
FYI, signal isn't the most suitable way to do this operation have a look to django-antipattern article about signals. If I were you I would use a custom User model and override its save method.
After registration email with email confirmation is sent to a new user. I created model
UserWithConfirmation with new field is_email_confirmed. I was following this https://docs.djangoproject.com/en/4.1/topics/auth/customizing/#extending-the-existing-user-model.
I want to have UserWithConfirmation created for each new user when user is saved. For now I have sth like this.
from django.db import models
from django.contrib.auth.models import User
class UserWithConfirmation(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="user_with_confirmation")
is_email_confirmed = models.BooleanField(default=False)
def __str__(self):
return self.user.username
class User:
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
create_user_with_confirmation(User)
def create_user_with_confirmation(user):
UserWithConfirmation(user=user)
UserWithConfirmation.save()
How to make it works?
Just have UserWithConfirmation extend User
class UserWithConfirmation(User):
is_email_confirmed = models.BooleanField(default=False)
and change the entry when the email is confirmed
I solved my problem using signals
I changed UserWithConfirmation to Profile
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
is_email_confirmed = models.BooleanField(default=False)
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
Here is my code for saving slug automatically. But it doesn't work and I don't know why! I can't be totally wrong. Help me to get out.
from django.db import models
from django.urls import reverse
from django.template.defaultfilters import slugify
class Article(models.Model):
title = models.CharField(max_length=50)
body = models.TextField()
slug = models.SlugField(null=False,unique=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article_detail', kwargs={'slug': self.slug})
def save(self, *args, **kwargs): # new
if not self.slug:
self.slug = slugify(self.title)
return super().save(*args, **kwargs)
But in django Admin panel I have to save slug manually But I want to save it automatically.
Help me to understand this. Thanks Good People.
exclude the slug field from Django Admin by creating a ModelAdmin class as below,
# admin.py
class ArticleAdmin(admin.ModelAdmin):
exclude = ('slug',)
admin.site.register(Article, ArticleAdmin)
So, set null=True and add blank=True.
slug = models.SlugField(null=True, blank=True, unique=True)
I have the model "Account" below:
class Account(models.Model):
email=models.EmailField(verbose_name="email", max_length=60, unique=True)
username=models.CharField(max_length=30, unique=True)
data_inscricao=models.DateTimeField(verbose_name='Data de Inscrição', auto_now_add=True)
ultimo_login=models.DateTimeField(verbose_name='ùltimo Login', auto_now_add=True)
def __str__(self):
return self.username
and this other "PersonalData"...
class PersonalData(models.Model):
id_user=models.OneToOneField(Account, on_delete=models.CASCADE)
nome_completo=models.CharField(max_length=56, unique=True, null=True)
email=models.EmailField(max_length=60, verbose_name="Email", unique=True, null=True)
cpf=models.CharField(max_length=14, unique=True, null=True, verbose_name="CPF")
rg=models.CharField(max_length=12, unique=True, null=True, verbose_name="RG")
idade=models.IntegerField(null=True)
data_nascimento=models.DateField(verbose_name="Data de Nascimento", null=True)
genero=models.CharField(max_length=8, choices=GENERO, null=True)
estado_civil=models.CharField(max_length=13, null=True, choices=ESTADO_CIVIL, verbose_name="Estado Civil")
def __str__(self):
return self.nome_completo
views.py
def cadastro_curriculo(request):
form = InsereDadosPessoais(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
return redirect("vagas")
return render(request, "personal/curriculo.html", {'form': form,})
forms.py
class InsereDadosPessoais(forms.ModelForm):
class Meta:
model = PersonalData
fields = '__all__'
I'ld like PersonalData.id_user use by default the Account.username of the loged user and I don't know how do that.
Just to exemplify, In Django Admin, my PersonalData model allows me to choose the user, but I want it to happen automatically and not manually.
Can someone help me?
at admin.py add the admin class as per the docs
assign exclude as per the docs
exclude = ('user',)
and at save_model
def save_model(self, request, obj, form, change):
obj.user = request.user
super().save_model(request, obj, form, change)
Check docs here
If you want to add this to normal views
forms.py
class XXForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(XXForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
obj = super(XXForm, self).save(commit=False)
obj.user = self.user
if commit:
obj.save()
return obj
views.py
def xxview(request, *args, **kwargs): # your args
if request.POST:
#your stuff
form = XXForm(request.POST......., user=request.user)
else:
# your stuff
Check views here
I think you are Brazilian too :) Welcome! I learned this from this site.
models.py
from django.contrib.auth import User
class PersonalData(models.Model):
id_user = models.OneToOneField(User, on_delete=models.PROTECT, null=True, blank=True)
cpf = models.CharField(max_length=14, unique=True, null=True, verbose_name="CPF")
rg = models.CharField(max_length=12, unique=True, null=True, verbose_name="RG")
idade = models.IntegerField(null=True)
data_nascimento = models.DateField(verbose_name="Data de Nascimento", null=True)
genero = models.CharField(max_length=8, choices=GENERO, null=True)
estado_civil = models.CharField(max_length=13, null=True, choices=ESTADO_CIVIL, verbose_name="Estado Civil")
data_inscricao = models.DateTimeField(verbose_name='Data de Inscrição', auto_now_add=True)
ultimo_login = models.DateTimeField(verbose_name='ùltimo Login', auto_now_add=True)
def __str__(self):
return '{} {}'.format(id_user.first_name, id_user.last_name)
def save_model(self, request, obj, form, change):
if not obj.id_user:
# Only set added_by during the first save.
obj.id_user = request.user
super().save_model(request, obj, form, change)
admin.py
from .models import PersonalData
class PersonalDataAdmin(admin.ModelAdmin):
readonly_fields = ('id_user',)
admin.site.register(PersonalData, PersonalDataAdmin)
Important notes:
You don't have to create a field that saves the full name, Django itself can do it for you.
If you are going to use Django-Admin you can work with permissions within it by own User models. Click here and read a little about.
I recommend you use the built-in User model, it would look like this. Feel free to access my profile and get my contact information, I would be happy to help you with your project!
I'd suppose you have to make id_user field a foreign key to Account identifier which you should add to your model. In your described scenario id_user will "use" Account.username which is not obligated to be unique among all the users registered in the system. So, I suggest you to create an id field for Account and utilize it as a numeral identifier for that model.
Also, if I do not mistake, Django has an intrinsic User model which is intended for usage in such cases. Of course, you can extend that model for adding specific attributes.
I want to change a names of items (users) in drop down list in Django Admin Model. I want to do it without any changes in basic models.
I just want to field 'user'(admin.py) refers to 'user' in Worker model(office.py) through username (just without Firstname and Lastname)
admin.py
from .models import Token
class TokenAdmin(admin.ModelAdmin):
model = Token
fieldsets = (
(None, {
'fields': ('name', 'key', 'user')
}),
models.py
from office.models import Worker
class Token(models.Model):
user = models.ForeignKey(
Worker,
related_name='auth_token',
verbose_name=_("api.models.token.user")
)
office.py
class Worker(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_("User"))
firstname = models.CharField(
_("Firstname"), blank=False, null=False, max_length=50)
lastname = models.CharField(
_("Lastname"), blank=False, null=False, max_length=50)
def __str__(self):
return "%s %s" % (self.lastname, self.firstname)
I have solved it!
admin.py
class UserChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.user
class TokenAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'user':
kwargs['form_class'] = UserChoiceField
return super(TokenAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)