Modifying the django-invitations Package to allow Team Functionality - python

Using django-invitations, a user can invite multiple emails at once to their team using the code below that I obtained from this question: How to associate invited users with the inviter's Company/group?
#login_required
def invite_multi_premium(request):
# Get users that are in the company's user database as well as users that have been invited
taskly_users = TasklyUser.objects.filter(team=request.user.team)
Invitations = get_invitation_model()
# I'm afraid this is going to get all invited users, not just those that belong to the company
invited_users = Invitations.objects.filter()
if request.method == 'POST':
form = InviteMultipleEmailsForm(request.POST)
print(request.POST, "THIS IS THE REQUEST POST")
invitees2 = request.POST['emails']
invitees = invitees2.split(', ')
for invitee in invitees:
Invitation = get_invitation_model()
try:
invite = Invitation.create(invitee, inviter=request.user, team=str(request.user.team))
invite.send_invitation(request)
except IntegrityError as e:
print(type(e))
print(dir(e))
return render(request, 'invitations/forms/_invite_multi.html', {
"form":form
})
else:
form = InviteMultipleEmailsForm()
return render(request, 'invitations/forms/_invite_multi.html', {
"form":form
})
When the user follows the invitation link, they are brought to a signup form (django allauth) with their email address pre-filled. When they sign up, they are not associated with the team that the Inviter is on. Here is the part of the package I modified to get "team" added to the Invitations model, but I can't get the "team" to pass from the Invitations model to the User model.
class Invitation(AbstractBaseInvitation):
email = models.EmailField(unique=True, verbose_name=_('e-mail address'),
max_length=app_settings.EMAIL_MAX_LENGTH)
created = models.DateTimeField(verbose_name=_('created'),
default=timezone.now)
team = models.CharField(max_length=255, null=True, blank=True)
#classmethod
def create(cls, email, inviter=None, team=None, **kwargs):
key = get_random_string(64).lower()
instance = cls._default_manager.create(
email=email,
key=key,
inviter=inviter,
team=team,
**kwargs)
return instance
def key_expired(self):
expiration_date = (
self.sent + datetime.timedelta(
days=app_settings.INVITATION_EXPIRY))
return expiration_date <= timezone.now()
def send_invitation(self, request, **kwargs):
current_site = kwargs.pop('site', Site.objects.get_current())
invite_url = reverse('invitations:accept-invite',
args=[self.key])
invite_url = request.build_absolute_uri(invite_url)
ctx = kwargs
ctx.update({
'invite_url': invite_url,
'site_name': current_site.name,
'email': self.email,
'team': self.team,
'key': self.key,
'inviter': self.inviter,
})
email_template = 'invitations/email/email_invite'
get_invitations_adapter().send_mail(
email_template,
self.email,
ctx)
self.sent = timezone.now()
self.save()
signals.invite_url_sent.send(
sender=self.__class__,
instance=self,
invite_url_sent=invite_url,
inviter=self.inviter)
def __str__(self):
return "Invite: {0}".format(self.email)

Solved it by moving the receiving signal into my app/models.py instead of in the app/signals.py. I read in this post: https://simpleisbetterthancomplex.com/tutorial/2016/07/28/how-to-create-django-signals.html that you should avoid putting the receiver in the models.py file but the explanation is lacking in detail.

Related

How Can I set and Get Django Form Value on Another View

I am working on a Django Ticketing project where I want guest to activate Ticket PIN and then register for the event they bought the ticket for. And I also want them to have login user access and be able to update profile immediately after login.
The application usually start with PIN activation and thereafter guest registration. The issue is that I don't know how to pass the PIN value from the PIN activation view to the guest registration view.
Notice that I have used request.session['pin'] = pin_value to set the PIN as the session variable in the pin activation view and got it using user_pin = request.session.get('pin') in the register guest view but only the Guest.objects.create(guest_name=new_user, pin=user_pin) in the register guest view gets the session variable while the Pin.objects.filter(value=user_pin).update(status='Activated') fails to get the session variable for the registration process to be completed. I have tried using a literal value in the Pin filter and update query and it worked but using the session variable does not.
Below are my models:
class Guest(models.Model):
guest_name = models.OneToOneField(User, on_delete=models.CASCADE, blank=True)
pin = models.CharField(max_length=6, default='No Pin', blank=True)
def __str__(self):
return f"{self.guest_name}"
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
surname = models.CharField(max_length=20, null=True)
othernames = models.CharField(max_length=40, null=True)
gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
phone = PhoneNumberField()
image = models.ImageField(default='avatar.jpg', blank=False, null=False, upload_to ='profile_images',
)
def __str__(self):
return f'{self.user.username}-Profile'
class Pin(models.Model):
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
value = models.CharField(max_length=6, default=generate_pin, blank=True)
added = models.DateTimeField(auto_now_add=True, blank=False)
reference = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
status = models.CharField(max_length=30, default='Not Activated')
#Save Reference Number
def save(self, *args, **kwargs):
self.reference == str(uuid.uuid4())
super().save(*args, **kwargs)
def __unicode__(self):
return self.ticket
class Meta:
unique_together = ["ticket", "value"]
def __str__(self):
return f"{self.ticket}"
def get_absolute_url(self):
return reverse("pin-detail", args=[str(self.id)])
My Views code:
def pin_activation(request):
if request.method == "POST":
#Create PIN form
form = PinActivationForm(request.POST)
#Get User Pin Value from Form
pin_value = form['pin'].value()
#Check if the the form has valid data in it
if form.is_valid():
try:
#Get user Pin with the one in the Database
check_pin_status = Pin.objects.get(value=pin_value)
except Pin.DoesNotExist:
messages.error(request, f'{pin_value} Does Not Exist')
return redirect('pin-activation')
else:
#Check PIN status
if check_pin_status:
#Get Event Ticket Date of the PIN
event_date = check_pin_status.ticket.event.date
#Get Current Date
current_date = datetime.now().date()
#Check if Event Date is Passed the Current Date
if event_date < current_date:
messages.error(request, 'Event Has Passed')
return redirect('pin-activation')
else:
#Update the User Pin with a new status of Activated
Pin.objects.filter(value=form['pin'].value()).update(status='Validated')
#Message the User
messages.success(request, 'Pin Validated Successfully')
#Redirect the user to register for seat
return redirect('register-guest')
#Check filter the DB where the PIN status is Validated
request.session['pin'] = pin_value
elif Pin.objects.filter(value=form['pin'].value(), status="Validated"):
messages.error(request, 'Pin Already Validated. Register for Seat')
return redirect('register-guest')
#Check Filter PIN in DB where Status is Activated
elif Pin.objects.filter(value=form['pin'].value(), status="Activated"):
messages.error(request, "Pin Already Activated, Login.")
return redirect('user-login')
else:
messages.error(request, 'Something Went Wrong. Try again')
else:
form = PinActivationForm()
context = {
'form':form,
}
return render(request, 'user/pin_activation.html', context)
def register_guest(request):
#get session variable
user_pin = request.session.get('pin')
form = GuestUserForm(request.POST)
page_title = "Festival Registration"
if request.method == 'POST':
form = GuestUserForm(request.POST)
pin_form = PinActivationForm(request.POST)
if form.is_valid() and pin_form.is_valid():
new_user = form.save()
Guest.objects.create(guest_name=new_user, pin=user_pin)
Pin.objects.filter(value=user_pin).update(status='Activated')
messages.success(request, 'Registered Successfully. Login')
return redirect('user-login')
else:
form = GuestUserForm()
pin_form = PinActivationForm()
context = {
'form':form,
'pin_form':pin_form,
'page_title':page_title,
}
return render(request, 'user/register.html', context)
Someone should please help with the best way of solving this problem. Thanks
you cannot save a quest as a User in this way.
Do something like this.
From youre form get the username.
Then create a new User with that username and create the Guest with that new user.
//simple form --> get it in youre template
class GuestUserForm(forms.Form):
username = forms.CharField()
password=forms.CharField()
//create new user from the form in template
user_guest = form.cleaned_data.get("username")
new_user = User.objects.create_user(username=user_guest)
//create new guest with created user
Guest.objects.create(guest_name=new_user)
//youre view function
def register_guest(request):
if request.method == 'POST':
form = GuestUserForm(request.POST)
if form.is_valid():
user_guest = form.cleaned_data.get("username")
print(user_guest)
new_user = User.objects.create_user(username=user_guest)
Guest.objects.create(guest_name=new_user)
form = GuestUserForm()
return render(request, "index.html",{"form":form})

Django is not populating correctly an specific form using a Queryset

I have created two models Leads and Deals, and I have coded some logic such that if you click a button the Lead becomes a Deal, so what I want it is that a new form is presented to the user but that form already contains the information from the Leads model.
#login_required
def close_lead(request):
if request.method == 'POST':
deal_form = DealForm(request.POST)
if deal_form.is_valid():
deal_form.save()
messages.success(request, 'You have successfully updated the status from open to Close')
id = request.GET.get('project_id', '')
obj = Leads.objects.get(project_id=id)
obj.status = "Closed"
obj.save(update_fields=['status'])
return HttpResponseRedirect(reverse('dashboard'))
else:
messages.error(request, 'Error updating your Form')
else:
id = request.GET.get('project_id', '')
obj = get_object_or_404(Leads, project_id=id)
print(obj.expected_revenue)
form = NewDealForm(request.POST or None, instance=obj)
return render(request,
"account/close_lead.html",
{'form':form})
I have done some debug and printed to the console the queryset and the information is fine, so the queryset is no the problem, the problem is that the NewForm doesn't prepopulate the new values.
models.py (only 2 models shown)
class Leads(models.Model):
CHOICES = (
('Illumination Studies','Illumination Studies'),
('Training','Training'),
('Survey Design','Survey Design'),
('Software License','Software License')
)
STATUS = (('Open','Open'),
('Closed','Closed'),
('Canceled', 'Canceled')
)
project_id = models.BigAutoField(primary_key=True)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
agent = models.ForeignKey(Profile, on_delete=models.CASCADE, default="agent")
created_at = models.DateTimeField(auto_now_add=True)
point_of_contact = models.ForeignKey(Client, on_delete=models.CASCADE)
expected_revenue = MoneyField(max_digits=14, decimal_places=2, default_currency='USD')
expected_licenses = models.IntegerField(blank=True)
country = CountryField(blank_label='(select country)')
status = models.CharField(max_length=10,choices=STATUS)
estimated_closing_date = models.DateField(blank=True)
services = models.CharField(max_length=20,choices=CHOICES)
def __str__(self):
return f'{self.company}'
class Deal(models.Model):
project_id = models.ForeignKey(Leads, on_delete=models.CASCADE, default='id')
agent = models.ForeignKey(Profile, on_delete=models.CASCADE, default="agent")
service = models.ForeignKey(Leads, on_delete=models.CASCADE, related_name='service')
closing_date = models.DateField(auto_now_add=True)
client = models.ForeignKey(Client, on_delete=models.CASCADE,default='client')
licenses = models.ForeignKey(Leads,on_delete=models.CASCADE, related_name='licenses')
revenue = MoneyField(max_digits=14, decimal_places=2, default_currency='USD')
comments = models.TextField(blank=True,null=True)
Now, it could be that I have to inherit from a different form?
forms.py (only NewDealForm)
class NewDealForm(forms.ModelForm):
class Meta:
model = Deal
fields = ['agent','client','project_id','service', 'licenses','revenue', 'comments']
Obviously, worst-case scenario is to create a dictionary to extract the data from the queryset and then pass it to the form, but I'm sure Django has a more elegant way to handle this process.
Well, I guess sometimes Stack Overflow pushes you to solve your own issues, this is the solution.
Essentially, the initial=queryset value was not initializing the form mainly because I have very specific relationships in my model, so what I did is to create a dictionary (key:value) with the form field as key, and my queryset from my model as the value, the code is as below:
'''
def close_lead(request):
if request.method == 'POST':
deal_form = DealForm(request.POST)
if deal_form.is_valid():
deal_form.save()
messages.success(request, 'You have successfully updated the status from open to Close')
id = request.GET.get('project_id', '')
obj = Leads.objects.get(project_id=id)
obj.status = "Closed"
obj.save(update_fields=['status'])
return HttpResponseRedirect(reverse('dashboard'))
else:
messages.error(request, 'Error updating your Form')
else:
id = request.GET.get('project_id', '')
obj = get_object_or_404(Leads, project_id=id)
m = obj.__dict__
keys = Leads.objects.get(project_id=m['project_id'])
form_dict = {'project_id':keys.project_id,
'agent':keys.agent,
'client':keys.point_of_contact,
'company':keys.company,
'service':keys.services
}
form = NewDealForm(request.POST or None,initial = form_dict)
return render(request,
"account/close_lead.html",
{'form':form})
'''
As you can see, I create an object dictionary because the forms are different, so they share some common values not all, and then I simply adapt the dictionary, nice and easy, but I somehow expected that Django somehow finds relationships by name?, but maybe the batteries are not included for this.

Why is my Query not working? 'Exception Value: Cannot use QuerySet for "Conversation": Use a QuerySet for "Profile" '

I am attempting to query Conversation, which has a many to many field called members. I am doing this so that I can then pass Conversation to my InstantMessage object because that object has a foreign key called conversation that attaches to Conversation. I need to check if members are apart of Conversation first, and then if so, get, or if not, create, and then pass that into my InstantMessage object. But for some reason, I am not able to query it and I don't understand why.
error
Exception Value:
Cannot use QuerySet for "Conversation": Use a QuerySet for "Profile".
views.py/message
def message (request, profile_id):
other_user = get_object_or_404(Profile,id=profile_id)
members = Conversation.objects.filter(members= request.user).filter(members= other_user)
conversation, created = Conversation.objects.get_or_create( members = members)
if request.method == 'POST':
form = MessageForm(request.POST, instance= request.user, sender=request.user, conversation = conversation, message=message, date=date)
if form.is_valid():
form.save()
return redirect ('dating_app:messages.html')
else:
conversation, created = Conversation.objects.get_or_create( members= [request.user, other_user])
form = MessageForm(instance= request.user, sender=request.user, conversation= conversation, message=message, date=date)
context = {'form' : form }
return render(request, 'dating_app:messages.html', context)
models.py/Conversatin and InstantMessage
class Conversation(models.Model):
members = models.ManyToManyField(settings.AUTH_USER_MODEL)
class InstantMessage(models.Model):
sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name= 'sender',on_delete=models.CASCADE )
conversation = models.ForeignKey(Conversation, on_delete=models.CASCADE)
message = models.TextField()
date = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.message

Function notifies commentor when the poster should get notified

If I comment on the post named "a", then I get a notification saying that I made the comment on "a" but the notification system should notify the user who created post "a".
I have a clue what to do, because I have done something similar (notifying the user who commented when there's a reply to that comment) thanks to some tutorial.
In models.py for notification, I have to send the right notification and connect to it. I'll post my full code, you can see the bottom function for the connecting, and this is the one I'm having problem with.
from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from django.db import models
from django.contrib.auth.models import User
from main.models import Post
from accounts.models import MyProfile
from .signals import notify
# Create your models here.
class NotificationQuerySet(models.query.QuerySet):
def get_user(self, recipient):
return self.filter(recipient=recipient)
def mark_targetless(self, recipient):
qs = self.unread().get_user(recipient)
qs_no_target = qs.filter(target_object_id=None)
if qs_no_target:
qs_no_target.update(read=True)
def mark_all_read(self, recipient):
qs = self.unread().get_user(recipient)
qs.update(read=True)
def mark_all_unread(self, recipient):
qs = self.read().get_user(recipient)
qs.update(read=False)
def unread(self):
return self.filter(read=False)
def read(self):
return self.filter(read=True)
def recent(self):
return self.unread()[:5]
class NotificationManager(models.Manager):
def get_queryset(self):
return NotificationQuerySet(self.model, using=self._db)
def all_unread(self, user):
return self.get_queryset().get_user(user).unread()
def all_read(self, user):
return self.get_queryset().get_user(user).read()
def all_for_user(self, user):
self.get_queryset().mark_targetless(user)
return self.get_queryset().get_user(user)
class Notification(models.Model):
sender_content_type = models.ForeignKey(ContentType, related_name='nofity_sender')
sender_object_id = models.PositiveIntegerField()
sender_object = GenericForeignKey("sender_content_type", "sender_object_id")
verb = models.CharField(max_length=255)
action_content_type = models.ForeignKey(ContentType, related_name='notify_action',
null=True, blank=True)
action_object_id = models.PositiveIntegerField(null=True, blank=True)
action_object = GenericForeignKey("action_content_type", "action_object_id")
target_content_type = models.ForeignKey(ContentType, related_name='notify_target',
null=True, blank=True)
target_object_id = models.PositiveIntegerField(null=True, blank=True)
target_object = GenericForeignKey("target_content_type", "target_object_id")
recipient = models.ForeignKey(settings.AUTH_PROFILE_MODULE, related_name='notifications')
read = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
objects = NotificationManager()
def __unicode__(self):
try:
target_url = self.target_object.get_absolute_url()
except:
target_url = None
context = {
"sender": self.sender_object,
"verb": self.verb,
"action": self.action_object,
"target": self.target_object,
"verify_read": reverse("notifications_read", kwargs={"id": self.id}),
"target_url": target_url,
}
if self.target_object:
if self.action_object and target_url:
return "%(sender)s %(verb)s <a href='%(verify_read)s?next=%(target_url)s'>%(target)s</a> with %(action)s" %context
if self.action_object and not target_url:
return "%(sender)s %(verb)s %(target)s with %(action)s" %context
return "%(sender)s %(verb)s %(target)s" %context
return "%(sender)s %(verb)s" %context
#property
def get_link(self):
try:
target_url = self.target_object.get_absolute_url()
except:
target_url = reverse("notifications_all")
context = {
"sender": self.sender_object,
"verb": self.verb,
"action": self.action_object,
"target": self.target_object,
"verify_read": reverse("notifications_read", kwargs={"id": self.id}),
"target_url": target_url,
}
if self.target_object:
return "<a href='%(verify_read)s?next=%(target_url)s'>%(sender)s %(verb)s %(target)s with %(action)s</a>" %context
else:
return "<a href='%(verify_read)s?next=%(target_url)s'>%(sender)s %(verb)s</a>" %context
def new_notification(sender, **kwargs):
kwargs.pop('signal', None)
recipient = kwargs.pop("recipient")
verb = kwargs.pop("verb")
affected_users = kwargs.pop('affected_users')
#super_user_qs = MyProfile.objects.get(user=Post.moderator),
''' this is wrong, It;s what I tried but failed
if super_user_qs:
super_user_instance = super_user_qs
new_note = Notification(
recipient=super_user_instance,
verb = verb, # smart_text
sender_content_type = ContentType.objects.get_for_model(sender),
sender_object_id = sender.id,
)
for option in ("target", "action"):
obj = kwargs.pop(option, None)
if obj is not None:
setattr(new_note, "%s_content_type" %option, ContentType.objects.get_for_model(obj))
setattr(new_note, "%s_object_id" %option, obj.id)
new_note.save()
the below works for notifying commentor who gets reply
'''
if affected_users is not None:
for u in affected_users:
if u == sender:
pass
else:
new_note = Notification(
recipient=recipient,
verb = verb, # smart_text
sender_content_type = ContentType.objects.get_for_model(sender),
sender_object_id = sender.id,
)
for option in ("target", "action"):
try:
obj = kwargs[option]
if obj is not None:
setattr(new_note, "%s_content_type" %option, ContentType.objects.get_for_model(obj))
setattr(new_note, "%s_object_id" %option, obj.id)
except:
pass
new_note.save()
else:
new_note = Notification(
recipient=recipient,
verb = verb, # smart_text
sender_content_type = ContentType.objects.get_for_model(sender),
sender_object_id = sender.id,
)
for option in ("target", "action"):
obj = kwargs.pop(option, None)
if obj is not None:
setattr(new_note, "%s_content_type" %option, ContentType.objects.get_for_model(obj))
setattr(new_note, "%s_object_id" %option, obj.id)
new_note.save()
notify.connect(new_notification)
And then in models.py I have comment and post models. the get_affected_user is the function that's used in comment views.py to notify affected_user I believe. (I followed a tutorial.)
class Comment(models.Model):
user = models.ForeignKey(MyProfile)
parent = models.ForeignKey("self", null=True, blank=True)
post = models.ForeignKey(Post, null=True, blank=True, related_name="commented_post")
#property
def get_origin(self):
return self.path
#property
def get_comment(self):
return self.text
#property
def is_child(self):
if self.parent is not None:
return True
else:
return False
def get_children(self):
if self.is_child:
return None
else:
return Comment.objects.filter(parent=self)
def get_affected_users(self):
"""
it needs to be a parent and have children,
the children, in effect, are the affected users.
"""
comment_children = self.get_children()
if comment_children is not None:
users = []
for comment in comment_children:
if comment.user in users:
pass
else:
users.append(comment.user)
return users
return None
class Post(models.Model):
title = models.CharField(max_length = 50)
moderator = models.ForeignKey(User)
views = models.IntegerField(default=0)
In views.py for comment, the above get_affected_user is used for notifying commentor who gets reply. I thought about using the same function to achieve what I want, but couldn't. So for that I just set get_affected_user to none for now.
def comment_create_view(request):
if request.method == "POST" and request.user.is_authenticated():
parent_id = request.POST.get('parent_id')
post_id = request.POST.get("post_id")
origin_path = request.POST.get("origin_path")
try:
post = Post.objects.get(id=post_id)
except:
post = None
parent_comment = None
if parent_id is not None:
try:
parent_comment = Comment.objects.get(id=parent_id)
except:
parent_comment = None
if parent_comment is not None and parent_comment.post is not None:
post = parent_comment.post
form = CommentForm(request.POST)
if form.is_valid():
comment_text = form.cleaned_data['comment']
if parent_comment is not None:
# parent comments exists
new_comment = Comment.objects.create_comment(
user=MyProfile.objects.get(user=request.user),
path=parent_comment.get_origin,
text=comment_text,
post = post,
parent=parent_comment
)
#affected_users = parent_comment.get_affected_users()
#print "this is"
affected_users = parent_comment.get_affected_users()
notify.send(
MyProfile.objects.get(user=request.user),
action=new_comment,
target=parent_comment,
recipient=parent_comment.user,
affected_users = affected_users,
verb='replied to')
messages.success(request, "Thank you for your response.", extra_tags='safe')
return HttpResponseRedirect(parent_comment.get_absolute_url())
else:
new_comment = Comment.objects.create_comment(
user=MyProfile.objects.get(user=request.user),
path=origin_path,
text=comment_text,
post = post
)
notify.send(
MyProfile.objects.get(user=request.user),
recipient = MyProfile.objects.get(user=request.user),
action=new_comment,
affected_users = None,
target = new_comment.post,
verb='commented on')
messages.success(request, "Thank you for the comment.")
return HttpResponseRedirect(new_comment.get_absolute_url())
else:
messages.error(request, "There was an error with your comment.")
return HttpResponseRedirect(origin_path)
else:
raise Http404
Edit:I'm having this problem for almost a week now.....I asked for some help from the instructor of the tutorial I purchased, and he only answers in short sentences(I can tell he doesn't absolutely care). Here are some hints he dropped. If I were to notify superuser
I should add the following to the models.py for notification,
super_user_qs = User.objects.filter(is_admin=True)
if super_user_qs.exists():
super_user_instance = super_user_qs.first()
new_note = Notification(
recipient=super_user_instance,
verb = verb, # smart_text
sender_content_type = ContentType.objects.get_for_model(sender),
sender_object_id = sender.id,
)
for option in ("target", "action"):
obj = kwargs.pop(option, None)
if obj is not None:
setattr(new_note, "%s_content_type" %option, ContentType.objects.get_for_model(obj))
setattr(new_note, "%s_object_id" %option, obj.id)
new_note.save()
but then I told him, I'm trying to notify post creator/moderator because any one can make post.(I told him this couple times/before he answered with the superuser one) I should use model post_save signal to create a new Notification within the model I'm working on. and I do not have to use the custom notify signal in this case.
Meanwhile, I was watching the tutorials over and over. I thought maybe I just need to change recipient = MyProfile.objects.get(user=post.moderator),
to the post.moderator but then I get Cannot assign "": "Notification.recipient" must be a "MyProfile" instance. so I did recipient = MyProfile.objects.get(user=post.moderator), but this notify to me about the comments I make...
I really await any advise
thank you
For you to notify the POST owner, it should be sent this way:
recipient = new_comment.post.moderator
instead of
recipient = MyProfile.objects.get(user=request.user)
This would send the notification to the moderator of the Post.
The way I see it is:
if parent_comment is not None: This line evaluates to false, so the recipient of the message is request.user.
You should make sure that this line parent_id = request.POST.get('parent_id') has a meaningful value
This line parent_comment = Comment.objects.get(id=parent_id) might be the culprit. Insert a print('!!!!!parent_id = ', parent_id) after this line, and see if you get in the console the id of an actual comment.
But that's what I suspect anyway, that the templates you created don't include this field in the form.
If you paste the template code, I might be able to help you debug.

Referral system like dropbox one

I want to implement a referral system to my system where registered users can invite other people by emailing their referral link (i.e. /register/referral/123123/) just like dropbox one ( and if a person signs up, the referrer gets additional bonus.
Currently I have implemented it this way:
Models:
class UserReferral(models.Model):
STATUS_INVITED = 1
STATUS_ACCEPTED = 2
STATUS_EXPIRED = 3
STATUS_CHOICES = (
(STATUS_INVITED, 'Invited'),
(STATUS_ACCEPTED, 'Accepted'),
(STATUS_EXPIRED, 'Expired'),
)
referrer = models.ForeignKey(User, related_name='referrers')
referred = models.ForeignKey(User, related_name='referred')
number = models.IntegerField()
status = models.IntegerField(choices=STATUS_CHOICES, default=STATUS_INVITED)
class Meta:
unique_together = (('referrer', 'referred'),)
def __unicode__(self):
return 'User %s referred %s' % (self.referrer.get_full_name(), self.referred.get_full_name())
#property
def referral_expired(self):
expiration_date = datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
return (self.status == self.STATUS_ACCEPTED or
(self.referred.date_joined + expiration_date <= datetime_now()))
Views:
This view is used by the registered users to send out new referral invites
#login_required
def invite_friends(request, template_name='accounts/invite_friends.html'):
if request.method == 'POST':
form = InviteForm(request.POST, user=request.user)
if form.is_valid():
emails = form.cleaned_data['emails']
for email in emails:
try:
user_referral = UserReferral.objects.get(referrer=request.user, referred__email=email)
except UserReferral.DoesNotExist:
random_username = ''.join(random.choice(string.ascii_uppercase) for x in range(6))
user = User.objects.create(username=random_username, password=email, is_active=False) # Dummy user to be overridden
user_referral = UserReferral.objects.create(referrer=request.user, referred=user, number=random.randint(10000, 99999))
send_mail('accounts/notifications/invite_friends', recipient_list=[email],
context={'user': request.user, 'number': user_referral.number})
messages.add_message(request, messages.SUCCESS, "Invites are sent.")
return redirect(reverse('profile_dashboard'))
else:
form = InviteForm(user=request.user)
return render(request, template_name, locals())
This is the URL where referred users can register, it basically calls the original register function with referral code, and check in the register view if the referral code is present, if so, it fetches the referred user instance from the UserReferral instance and populates the user data from the register form and saves that new user.
def referred_signup(request, referral_code):
user_referral = get_object_or_404(UserReferral, number=referral_code)
if user_referral.referral_expired:
raise Http404
response = register(request, referral_code=referral_code)
return response
So I create the dummy inactive 'referrer' User account every time the new invite is generated. And when on the registration time, I populate the names, password etc. from the user input form, and change the UserReferral instance status to ACTIVATED. Is there any better alternative to this one?

Categories