i'm sending notifications to a user via django notifications. And i have username regex working on the html so anyone comments with #username it will post and the html is linkable so click on the #username it will take him to the username profile page. Now i am using django signals to match the username and print out the username. but when i use notify to send the notification. it does not work.
models.py:
class Comment(models.Model):
post = models.ForeignKey(post, on_delete=models.CASCADE, related_name='comments')
user = models.ForeignKey(User, on_delete=models.CASCADE)
reply = models.ForeignKey('Comment', null=True, related_name='replies', on_delete=models.CASCADE)
content = models.TextField()
image = models.ImageField(upload_to='comments-pics', null=True, blank=True)
voice_record = models.FileField(upload_to='voice-comments', null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__ (self):
return '{}.{}'.format(self.post.title, str(self.user.username))
def save(self, *args, **kwargs):
super(Comment, self).save(*args, **kwargs)
def Comment_save_receiver(sender, instance, created, *args,**kwargs):
if created and not instance.parent:
user_regex = r'#(?P<username>[\w.#+-]+)'
m = re.search(user_regex, instance.content)
if m:
try:
recipient = User.objects.get(username=m.group('username'))
except (User.DoesNotExist, User.MultipleObjectsReturned):
pass
else:
notify.send(instance.user, recipient=recipient, actor=instance.user, verb='mention you in a post', target=instance, nf_type='tagged_by_one_user')
post_save.connect(Comment_save_receiver, sender=post)
the problem has been solved. i did wrong with the signal portion. it will be:
def comment_save_receiver(sender, instance, created, *args,**kwargs):
if created:
user_regex = r'#(?P<username>[\w.#+-]+)'
m = re.search(user_regex, instance.content)
if m:
try:
recipient = User.objects.get(username=m.group('username'))
except (User.DoesNotExist, User.MultipleObjectsReturned):
pass
else:
notify.send(instance.user, recipient=recipient, actor=instance.user, verb='mention you in a post', target=instance.post, nf_type='tagged_by_one_user')
post_save.connect(comment_save_receiver, sender=Comment)
Related
I am currently challenge with a like functionality on a group page for that I'm creating, the problem is that when a first user of the group post on the group page other users can comment and like at his post, but as soon as a second user of the same group post, then when the post get liked or commented on, it throws thess error DoesNotExist at /group/3/. i wonder why am getting this error, because when the first user posted it didn't throw that error, when his post got liked or commented on, but the error only shows up when a another user on the same group post and it got like or commented on. I would appreciate some help. Here is my like function view.
def like(request, pk):
user = request.user
post = Post.objects.get(pk=pk)
group = GroupEx.objects.get(group=pk)
liked= False
like = Like.objects.filter(username=user, post=post,group=group)
if like:
like.delete()
else:
liked = True
Like.objects.create(username=user, post=post, group=group)
resp = {
'liked':liked
}
response = json.dumps(resp)
return redirect('group:main', pk=pk)
return HttpResponse(response,content_type = "application/json")
Here is my comment view.
def comment(request, pk):
context = {}
user = request.user
post = get_object_or_404(Post, pk=pk)
group = get_object_or_404(GroupEx,pk=pk)
if request.method == 'POST':
form = NewCommentForm(request.POST)
if form.is_valid():
data = form.save(commit=False)
data.post = post
data.group = group
data.username = user
data.save()
return redirect('group:main', pk=pk)
else:
form = NewCommentForm()
context['form'] = form
return render(request,'group/grouptimeline.html',context)
Here this model for the group post .
class Post(models.Model):
group = models.ForeignKey(GroupEx, on_delete=models.CASCADE, related_name="group_post")
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE ,related_name="group_user")
description = models.TextField(max_length=500, blank=True)
pic = models.ImageField(upload_to='path/post/img' ,blank=True)
date_posted = models.DateTimeField(auto_now_add=True)
tags = models.CharField(max_length=100, blank=True)
class Comment(models.Model):
group = models.ForeignKey(GroupEx, on_delete=models.CASCADE, related_name="group_comment")
post = models.ForeignKey(Post, related_name='g_comments', on_delete=models.CASCADE, null=True, blank=True)
username = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='g_comments', on_delete=models.CASCADE,null=True)
comment = models.CharField(max_length=5000)
class Like(models.Model):
group = models.ForeignKey(GroupEx, on_delete=models.CASCADE, related_name="group_liker")
username = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='g_likes', on_delete=models.CASCADE)
post = models.ForeignKey(Post, related_name='g_likes', on_delete=models.CASCADE)
like_date = models.DateTimeField(auto_now=True)
comment_date = models.DateTimeField(auto_now_add=True)
in order to generate the full url in the email I send to the ticket purchaser, I have to access get_current_site in my models.py. To do so I pass request like this: get_absolute_url(request)
Is there anything wrong in doing it that way, or would you consider this as good code/approach?
def checkout_page(request):
[...]
#Send email
subject = render_to_string('checkout/email/your_ticket_subject.txt', {})
to_email = [transaction_profile.cleaned_data['email'],]
email_ticket_link = t.get_absolute_url(request, email=True)
content = render_to_string('checkout/email/your_ticket_message.txt', {'email_ticket_link': email_ticket_link,})
send_mail(subject, content, settings.DEFAULT_FROM_EMAIL, to_email)
ticket_link = t.get_absolute_url(request)
return redirect(ticket_link)
models.py
class TicketPurchase(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE) #change CASCADE
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE) #change CASCADE
ticketpurchase_id = models.CharField(max_length=10, unique=True)
refunded = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True)
update = models.DateTimeField(auto_now=True)
def get_absolute_url(self, request, email=False):
ticket_link = reverse("ticketsgenerator:show_tickets",
kwargs={"order_id": self.order.order_id, "customer_key": self.order.customer_key}
)
if email:
current_site = get_current_site(request)
return 'https://{}{}'.format(current_site, ticket_link)
return ticket_link
I created a custom user model called Agent by extending AbstractUser. Now for some reason, my signup page is stuck and I can't figure out why (it was working fine before I created the custom user). When I click the Sign Up button, the page is stuck on Waiting for localhost...
There are 2 additional models on top of Agent that are created during registration - AgentBasicInfo and AgentPremiumInfo. AgentBasicInfo is displayed on the sign up page, while AgentPremiumInfo is created in the background, and not actually displayed during registration.
When I check my admin page, I see that an Agent model has been created, but no AgentBasicInfo and AgentPremiumInfo instances have been created. This leads me to believe something is getting stuck at or after agent_basic_info = basic_info_form.save(commit=False), but I can't figure out what it is.
Here is my code:
views.py
def signup(request):
if request.user.is_authenticated:
return HttpResponseRedirect('../dashboard/')
if request.method == 'POST':
signup_form = SignupForm(request.POST)
basic_info_form = AgentBasicInfoForm(request.POST)
if signup_form.is_valid() and basic_info_form.is_valid():
agent = signup_form.save(commit=False)
agent.is_active = False
agent.save()
# Creates a basic info form with user input
agent_basic_info = basic_info_form.save(commit=False)
agent_basic_info.agent = agent
agent_basic_info = agent_basic_info.save()
# Creates a profile model with the agent's premium information, empty except for 'agent' field. No actual form displayed on sign up page.
agent_premium_info = AgentPremiumInfo.objects.create(agent=agent)
agent_premium_info.save()
current_site = get_current_site(request)
message = render_to_string('acc_active_email.html', {
'agent':agent,
'domain':current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(agent.pk)),
'token': account_activation_token.make_token(agent),
})
mail_subject = 'Activate your blog account.'
to_email = signup_form.cleaned_data.get('email')
email = EmailMessage(mail_subject, message, to=[to_email])
email.send()
return HttpResponse('Please confirm your email address to complete the registration')
else:
signup_form = SignupForm()
basic_info_form = AgentBasicInfoForm()
return render(request, 'signup.html', {'signup_form': signup_form, 'basic_info_form': basic_info_form})
def activate(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
agent = Agent.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError, Agent.DoesNotExist):
agent = None
if agent is not None and account_activation_token.check_token(agent, token):
agent.is_active = True
agent.save()
login(request, agent)
# return redirect('home')
return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
else:
return HttpResponse('Activation link is invalid!')
models.py
class Agent(AbstractUser):
pass
class AgentBasicInfo(models.Model):
TITLE = (
('Salesperson', 'Salesperson'),
('Sales Representative', 'Sales Representative'),
('Broker', 'Broker'),
('Broker of Record', 'Broker of Record'),
)
agent = models.OneToOneField(Agent, on_delete=models.CASCADE)
agent_first_name = models.CharField(max_length=30)
agent_last_name = models.CharField(max_length=30)
agent_preferred_email = models.EmailField()
office_phone_number = models.CharField(max_length=10)
agent_brokerage = models.CharField(max_length=50)
agent_title = models.CharField(max_length=20, choices=TITLE)
class AgentPremiumInfo(models.Model):
agent = models.OneToOneField(Agent, on_delete=models.CASCADE)
agent_phone_number = models.CharField(max_length=10, blank=True, null=True)
agent_website = models.CharField(max_length=50, blank=True, null=True)
agent_biography = models.TextField(blank=True, null=True)
agent_address_street = models.CharField(max_length=50, blank=True, null=True)
agent_address_city = models.CharField(max_length=25, blank=True, null=True)
agent_address_province = models.CharField(max_length=2, choices=PROVINCE, blank=True, null=True) # Add province choices later
agent_address_postal_code = models.CharField(max_length=6, blank=True, null=True)
agent_picture = models.ImageField(height_field=200, width_field=100, blank=True, null=True)
forms.py
class SignupForm(UserCreationForm):
email = forms.EmailField(max_length=200, help_text='Required')
def clean_email(self):
data = self.cleaned_data['email']
if not data.endswith('#gmail.com'):
raise forms.ValidationError("You must use your #gmail.com Email")
return data
class Meta:
model = Agent
fields = ('username', 'email', 'password1', 'password2')
class AgentBasicInfoForm(forms.ModelForm):
class Meta:
model = AgentBasicInfo
fields = ['agent_first_name', 'agent_last_name', 'agent_preferred_email', 'office_phone_number', 'agent_brokerage', 'agent_title']
class AgentPremiumInfoForm(forms.ModelForm):
class Meta:
model = AgentPremiumInfo
fields = ['agent_phone_number', 'agent_website', 'agent_biography', 'agent_picture', 'agent_address_street', 'agent_address_city', 'agent_address_province', 'agent_address_postal_code']
It seems something was wrong in the database despite me doing a reset_db. I did another reset_db and it magically fixed the issue.
I am using GroupRequiredMixin from braces.views trying to limit the access to some views to a specific group of users.
My view looks like this:
class InviteCompanyAdminView(LoginRequiredMixin, GroupRequiredMixin, CreateView):
model = CompanyAdminInvitation
group_required = u"staff" # For the GroupRequiredMixin
success_url = '/'
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
# It should return an HttpResponse
form.instance.send_invite(self.request)
return super(InviteCompanyAdminView, self).form_valid(form)
I am accessing the view with a user that doesn't belong to any group and yet the view is rendered. Any idea why?
My model looks like this:
class CompanyAdminInvitation(models.Model):
user_first_name = models.CharField(max_length=128)
user_last_name = models.CharField(max_length=128)
user_title = models.CharField(max_length=128)
user_email = models.EmailField()
company_name = models.CharField(max_length=128)
company_country = CountryField()
invitation_uid = models.CharField(max_length=100, null=True, blank=True, unique=True, editable=False)
has_been_used = models.BooleanField(default=False, editable=False)
invitation_date = models.DateTimeField(auto_now_add=True)
def __init__(self, *args, **kwargs):
super(CompanyAdminInvitation, self).__init__(*args, **kwargs)
self.invitation_uid = str(uuid4())
def send_invite(self, request):
# TODO use a template instead of hardcoding the email
subject = "Get started with your account!"
message = "Hi, your link to start is %s" % \
(request.build_absolute_uri(reverse("users:admin_signup",
kwargs={"invite_id": str(self.invitation_uid)})))
from_email = "no-reply#example.com"
recipient_list = [self.user_email,]
send_mail(subject=subject, message=message, from_email=from_email, recipient_list=recipient_list)
def get_absolute_url(self):
return "/"
I am not sure if it is the cause of the original posters problem, but this can be caused if testing with a superuser, which will ignore the group permissions in Braces (see issue #105 for django-braces)
Try testing with a non-superuser to fix this issue.
I have a class Task with the following implementation:
class Task(models.Model):
author = models.ForeignKey(Author, unique=False)
name = models.CharField(max_length=255)
completed = models.BooleanField(default=False)
deadline = models.DateTimeField(null=True, blank=True)
pub_date = models.DateTimeField(auto_now_add=True, editable=False)
edit_date = models.DateTimeField(auto_now_add=True, auto_now=True, editable=False)
tag = models.ManyToManyField(Tag, related_name='tags', null=True, blank=True, default=None)
# group = models.ForeignKey(Group, blank=True, default=None)
def __str__(self):
return u'%s' % (self.name)
def toggle_complete(self):
self.completed = not self.completed
def is_past_deadline(self):
return timezone.now() > self.deadline
And I am trying to do a simple form that creates a new Task with a Title. But, as you can see, the author attribute can not be null (and don't want to, of course).
Author is implemented as follows:
class Author(models.Model):
user = models.OneToOneField(User, primary_key=True)
name = models.CharField(max_length=30)
def __str__(self):
return u'%s' % (self.user)
I tried and tried to hide the author field and, overriding methods like get_form_kwargs, form_valid, get_form to set it to the current logged user, but I always fail. Simply, the id is neither sent as post data (as seein in the debug trace), nor fetched from the view itself.
My best result has been showing the author field, creating the user correctly, but getting a "success_url" not found, even with the model having a get_absolute_url method declared.
The view I am working with is implemented like:
class HomeView(CreateView, MultipleObjectMixin):
# common
model = models.Task
template_name = 'home.html'
#form
form_class = TaskForm
# list
object_list = model.objects.all()
context_object_name = 'tasks'
paginate_by = 40
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('taskr:index'))
return super(HomeView, self).dispatch(request, *args, **kwargs)
def get_form_kwargs(self):
kwargs = super(HomeView, self).get_form_kwargs()
kwargs['initial']['author_id'] = self.request.user.id
return kwargs
def form_valid(self, form):
task = form.save(commit=False)
task.user = models.Author.objects.get(user=self.request.user) # use your own profile here
task.save()
return HttpResponseRedirect(self.get_success_url())
For the record, the MultipleObjectMixing part of the view works flawlessly.
I am desperate, is there any good resource for Django forms, one like http://ccbv.co.uk/? Thanks.
After a good night sleep, while cleaning up, I tried fixing the form_valid in the CreateView descendant and I got it right.
The trick is in
task.user = models.Author.objects.get(user=self.request.user)
and it failed to me because of desperate copy-pasting. The problem was that my Task model has no user attribute, but an author. So
task.author = models.Author.objects.get(user=self.request.user)
fixes it all.
Sorry for the stupid question.