Sending user-dependent scheduled emails with celery and django? - django

I'd like for my web-app to send weekly / monthly emails to the users - how would I limit celery to only send scheduled emails to the users that "opt-in"?
I installed django-celery-beat and I can configure a cron job in the admin interface, but not only to specific users

You'd need to add a field to your User model to store if the user has opted-in or out for emails. Below is pseudo code and assumes you have extended Django with a custom User model of your own.
models.py:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
email_opt_in = models.BooleanField(default=False)
# Other code ...
tasks.py:
from .models import User
#app.task
def send_daily_email():
# Get all users that are active and opted-in for emails
users = User.objects.filter(is_active=True, email_opt_in=True)
for user in users:
# Code to generate and send email

Related

How to login to Django Admin panel with user I created in this panel? User model was extended

The model itself:
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserModel(AbstractUser):
class UserType(models.TextChoices):
MANAGER = 'm', 'Manager'
CUSTOMER = 'c', 'Customer'
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
type = models.CharField(choices=UserType.choices, max_length=1)
USER_MODEL is registered in settings.py.
in admin.py it's registered as:
from django.contrib import admin
from .models import UserModel
admin.site.register(UserModel)
I can create new model in the panel with existing superuser I have. i.e. - it works.
I can add new super users with manage.py and they appear in the same place in the panel.
But later on I can't login with users I created in that panel.
saff status - checked.
The problem might be with passwords, because those created with createsuperuser shown hashed in the panel or I don't know even.
If I did smth completely wrong - let me know, I only need to extend users to have a couple of additional fields.
Django version 3.2
No worries django doesn't store raw passwords it always hash the password for security reasons, imagine someone hacked into your database people usually use the same password for all websites, not nice huh?!
so try python manage.py changepassword <user_name> and write your new password
and access the shell to check is_staff attr

How to connect inbuilt User database to another one in Django?

I am a beginner in Django. I have created a login, logout and register pages for my Django projects. When a user signs in I want them to only the posts that they have made. I am not sure how to make the users that I already have be able to login into their own pages and manage their budgets and etc.
Image of code
from django.db import models
from django.contrib.auth.models import User# user authentication
from django.contrib.auth import get_user_model#for connecting the inbuild user database
class List(models.Model):
user = models.ForeignKey(User)
item = models.CharField(max_length=200)#field to type the name of the budget
completed = models.BooleanField(default=False)#this needs to be changed later
def __str__(self):
return self.item + ' | ' + str(self.completed)
Django contrib auth is a good way to handle basic user system https://docs.djangoproject.com/en/3.1/ref/contrib/auth/. Then you can use request.user when a user is logged in, filter a queryset in your view and and show them just their posts or lists List.objects.filter(user=request.user)

How model field will be field automatically with the user ids

I am creating a payment/paid-subscription for my django project. I decided to create a separate payment app and connect it to my django project. In below, you see the model for payment which I expect to have user ids with their payment status(for now just want to start with default=False):
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Payment(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
paid = models.BooleanField(default=False)
class Meta:
db_table = 'payment'
I created this, but in the database table, I see the user_id and
paid are empty, while I have already a lot of users signed up. How
to bring those ids here, with a default false paid?
And what should I do to say django that after each new sign up fill
this model as well?
Part 1 - Updating existing users to have a Payment
Django won't automatically do this for you, you can go into the shell, and create Payment instances for each user:
Enter the shell (python manage.py shell)
from myapp.models import Payment
users = User.objects.all()
for user in users:
Payment.objects.create(user=user, paid=False)
If you want to be more effecient you could do something like this:
payments = [Payment(user=user, paid=False) for user in User.objects.all()]
Payment.objects.bulk_create(payments)
If this is an app that you have already deployed somewhere else you should create a data-migration to do this for you:
from django.db import migrations
def create_payments(apps, schema_editor):
Payment = apps.get_model('yourappname', 'Payment')
User = apps.get_model('yourappname', 'User')
payments = [Payment(user=user, paid=False) for user in User.objects.all()]
Payment.objects.bulk_create(payments)
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
migrations.RunPython(create_payments),
]
Part 2 - Creating Payments on every new sign-up
This will depend alot on how you are doing your sign-ups, so its difficult to give an exact answer. But wherever your new user object is created you just want to add something like:
Payment.objects.create(user=user, paid=False)
If you have a form that is handling user sign-ups maybe do it in the save method of that form. If you're using something like django rest framework, it would go in whatever view creates the User.

Django: how to store information of multiple logins of the same user from different devices

In Django User model, we store the last_login to know when is the users last login.
But assuming i am logging from firefox and chrome browsers and I want to store the information of the device and its login time, how can we do that.
Later i can see from where all the devices the user is currently logged in and what times is logged in from those devices.
Consider creation of a new model with relation many to one to application User.
This model named say UserSession could store information such as device type, login time etc. and could be easily queried for given user.
import datetime
from django.conf import settings
from django.db import models
from django.utils import timezone
class UserSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
device_type = models.CharField(max_length=255)
login_time = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
Instance of this model could be created on each new login time.

Extending Django-Admin Login (username, password, sites)

I'm trying to extend Django Admin Login. Most of the resources pointed towards extending views after the Login.
I wanted to add sites to the Login criteria.
So instead of
Username
Password
It will be
Username
Password
Site
Such that the Site will check whether the user belongs to the Site as admin and if it is, it will load only data belongs to the site.
Thanks
Cheers,
Mickey
I am not sure because I am newbee in django.
I would copy the admin code from the original django code in my profject folder. Then I would change it like you want it and put it in installed apps.
I hope, I could help you. As I said, I am a newbee in django.
Craphunter
You use user profiles for this.
Here's a basic example (this code would go in your app's models.py):
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
# Define a signal handler to be called after saving
# a User object
def user_save_handler(sender, **kwargs):
# If the save was creating a new user as opposed
# to updating an existing one, then create a
# UserProfile object and associate it with the User
if kwargs['created']:
# kwargs['instance'] is the User object we just
# created
UserProfile(user=kwargs['instance']).save()
# Hook the signal handler up to the User model's post_save
# signal
post_save.connect(user_save_handler, sender=User)
# Define your UserProfile class as usual.
class UserProfile(models.Model):
# user is a one-to-one reference to the associated
# User object. You need this field
user = models.OneToOneField(User)
# Now define any other fields you care about
birthday = models.DateField()