I'm currently working on a social network site with Django.
I am working on the "tag" feature, which sends a Notification to a user whenever they are tagged in a Post.
I created a post_save signal like this:
def post_tagged(*args, **kwargs):
instance = kwargs['instance']
message = f'{instance.user.slug} mentioned you in a post.'
#Find in the content of the post if there are any "#username", if yes create a Notification object
for user in MyUser.objects.all():
if instance.content.find(f'#{user.slug}') != -1 and instance.user != user:
Notification.objects.create(user = user, message = message)
models.signals.post_save.connect(post_tagged, sender = Post)
This is working fine when I create a new Post, but it also triggered when I delete a Post. This is the code in the view to delete a post:
if 'deletePost' in request.POST:
postId = request.POST.get('deletePost', None)
post = Post.objects.get(pk = postId)
if request.user == post.user:
post.delete()
message = 'Success'
else:
message = 'Fail'
jsonData = {"message": message,}
return HttpResponse(json.dumps(jsonData))
Also if it helps you can see I'm using ajax to send the request to the view. And the delete is also working fine. The only problem is that it also create a Notification to the tagged users when I delete a post.
Anyone having the same issue? I appreciate any help. Thanks
Related
I am trying to add messaging functionality to my web app made in Django.
So far, I have managed to successfully send and receive messages from user to user.
But, now I have been stuck at showing all the conversation lists to the inbox.html page of the logged user.
I have tried different approaches that I can think of but can not get the expected result.
models.py
class Messaging(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sender')
receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name='receiver')
message_text = models.TextField(max_length=360, verbose_name='Write Message')
message_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.sender}\'s Message to {self.receiver}'
viwes.py
Function to send and receive messages from user to user
#login_required
def messageview(request, user_name):
sender_user = request.user
receiver_user = User.objects.get(username=user_name)
message_list = Messaging.objects.filter(sender=sender_user, receiver=receiver_user).order_by('message_date') | \
Messaging.objects.filter(receiver=sender_user, sender=receiver_user).order_by('message_date')
if request.method == 'POST':
msg_text = request.POST.get('msg_text')
messaging = Messaging()
messaging.sender = sender_user
messaging.receiver = receiver_user
messaging.message_text = msg_text
messaging.save()
return redirect(request.META['HTTP_REFERER'])
context = {
'sender_user': sender_user,
'receiver_user': receiver_user,
'message_list': message_list,
}
return render(request, 'message.html', context)
Now I want to create an inboxview in views.py that will render all the conversation of the logged user.
Suppose I have two users in the database A and B, they have exchange 4 messages between them. What I want is to show the conversation as a list, which is in this case only one. For example, the logged user is A, he exchanges messages with user B and C. The inbox will show two rows. When user A clicks on either of the rows, he will be taken to the details message page corresponding to the user. It is kinds of like WhatsApp or messenger. I hope I can explain.
Edited: Added example image for better understanding
I am able to do this:
I need help to do this:
Please guide me the way.
You could try something like this.
This view will query the Messaging model and get all entries where sender or receiver is the logged in user.
#login_required
def inbox(request, user):
# Get all the records where either sender OR receiver is the logged in user
messages = Messaging.objects.filter(sender=request.user) | Messaging.objects.filter(receiver=request.user)
context = {'messages': messages}
return render(request, 'inbox.html', context)
You can add any extra lines of code to the above code that suits your requirements.
inbox.html
{% for message in messages %}
# You can show your message details here
{% endfor %}
I am building a drf backend api for my android app. I need the API to be able to send friend requests to the relevant users from a user. To do this I am using the django-friendship library. In their documentation they say:
Create a friendship request:
other_user = User.objects.get(pk=1)
Friend.objects.add_friend(
request.user, # The sender
other_user, # The recipient
message='Hi! I would like to add you') # This message is optional
My question is where should this code be written. I know that it belongs in a view, but what kind of view? Could someone give me an example?
I would probably add it to the view that handles any update to the users friendships. For example, if you have a view that handles submission of a friend requests via some endpoint it might look like this:
class CreateFriendRequestView(APIView):
def post(self, request, *args, **kwargs):
other_user = User.objects.get(pk=request.data['other_user'])
Friend.objects.add_friend(
request.user,
other_user,
message='Hi! I would like to add you')
return Response({'status': 'Request sent'}, status=201)
Maybe I am not asking the right question in the search area, but I can't find an answer for this. I am pretty sure that many people have this use case, but as a beginner in Django + Python, I need to ask it.
I have user that fills up a form and the data is stored in the database. Basically this form asks for an access to a Database and after the form is submitted I want my program to send an email to the user's manager and to the DBA to APPROVE or DENY it. Very simple, right?
My idea is that in this e-mail I send two URL's, one for approving and one for denying the request. When the URL the is clicked I send a response to the server with an update in the manager_approval field.
Has anyone implemented this solution, or could point me to something that could help me?
I am doing everything using Django + Python.
Regards,
Marcos Freccia
Basically this technique used in email verification. This is where you should look into.
Let's say you have model, named request, which has field like username to identify the person who requested access, database name, well, everything. But it will also have two "password-like" fields which will be used to determine if request was declined or not.
class Request(models.Model):
user = models.ForeignKey ...
databasename =
date =
...
access_granted = models.BooleanField(default=False)
deny_token = models.CharField()
allow_token = models.CharField()
The point is to generate those tokens on saving request in the View:
if request.method == POST:
form = RequestForm(request.POST)
if form.is_valid():
data['user'] = form.cleaned_data['user'])
data['databasename'] = form.cleaned_data['databasename'])
...
data['access_token'] = GENERATE_USING_HASH_FUNCTION()
data['deny_token'] = GENERATE_USING_HASH_FUNCTION()
form.save(data)
Then you can use module EmailMultiAlternatives to send html email like so:
subject, from_email, to = 'Request', 'admin#example.com', form.cleaned_data['manager_email']
html_content = render_to_string(HTML_TEMPLATE, CONTEXT) # Just as any regular templates
text_content = strip_tags(html_content)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to], reply_to=["admin#example.com"])
msg.attach_alternative(html_content, "text/html")
msg.send()
And inside that template you construct reverse url:
{% url 'app:grant_access' allow_token=token %} # "token" you get from context
{% url 'app:deny_access' deny_token=token %} # will become example.com/deny_access/7ea3c95, where 7ea3c95 is token
Then add lines to urls.py of your app like that:
url(r'^allow_access/(?P<allow_token>[0-9]+)$', CheckAcessView.as_view(), name="app:grant_access"),
url(r'^deny_access/(?P<deny_token>[0-9]+)$', CheckAcessView.as_view(), name="app:deny_access"),]
Then create CheckAcessView view. Where you access request stored in your database and check if, for example, parameter of url "allow_token" is equal stored allow_token. If so, change request status to allowed.
we are using django-contrib-comments in are project for communication between stuff and clients. Staff communication work's internally and I've made a custom email notification system which will notify you every time some other stuff member left a comment on your page.
Now the problem that I'm facing is that the user who want's to reply to a comment will only notify it's self and not the staff member who left a comment.
Email notification setup is made of two parts, first part is for the staff member who is leaving a comment and second is for the user who is replying to the comment.
Problem is how to refer to the user who all ready left a comment, I need his email, so I could add him to the recipient list so he will be notify when someone else replies to the comment.
comment.user and comment.user_email are things on which you refer on the comment model, but I can not find how to refer to user_email who's all ready left a comment when you want to reply to it, this part of the documentation explain model fields, I can understand that
user_email - The email of the user who posted the comment.
and it is perfect in the first part, but in the second it will refer to the user who is leaving a comment and that is why the other one will not be notified, so can someone please help me better understand how to refer to the user_email on which I'm replying, so I can make it work properly.
def send_comment_posted_emails(self, comment):
comment_user = comment.user
comment_user_email = comment.user_email
comment_text = comment.comment
handler_user = self.account_handler
handler_email = handler_user.email
# First part
if handler_email is not None and handler_email != comment_user.email:
current_site = Site.objects.get_current()
sub_org_url = self.get_view_url() + "#CommentsDiv"
ctx = {"sub_org_url": sub_org_url, "site_name": current_site.name, "sub_org_sn": self.serial_number,
"posted_name": user_util.get_user_full_name_or_user_name(comment_user),
"comment_text": comment_text}
subject = render_to_string("clients/emails/email_sub_org_comment_posted_subject.txt", ctx)
subject = "".join(subject.splitlines())
message = render_to_string("clients/emails/email_sub_org_comment_posted_message.html", ctx)
MailManager.send_mail_with_error_handler(subject, message, settings.DEFAULT_FROM_EMAIL,
[handler_email, comment_user_email], message_html=message)
# Second part
if handler_email is not None and handler_email == comment_user.email:
current_site = Site.objects.get_current()
sub_org_url = self.get_view_url() + "#CommentsDiv"
ctx = {"sub_org_url": sub_org_url, "site_name": current_site.name, "sub_org_sn": self.serial_number,
"posted_name": user_util.get_user_full_name_or_user_name(comment_user),
"comment_text": comment_text}
subject = render_to_string("clients/emails/reply_to_email_sub_org_comment_posted_subject.txt", ctx)
subject = "".join(subject.splitlines())
message = render_to_string("clients/emails/reply_to_email_sub_org_comment_posted_message.html", ctx)
MailManager.send_mail_with_error_handler(subject, message, settings.DEFAULT_FROM_EMAIL,
[handler_email, comment_user_email], message_html=message)
I found that django-contrib-comments are now composed/divided out in two separate libraries,
django-fluent-comments
django-threadedcomments
so in the threadedcomments there is a parent model field on which you can related when you are replying to a comment so, I've just made something like comment.parent.user_email and I've checked if parent is defined, and not None, and problem solved.
I have read, read, and read again the documentation and do many search on the Web but I don't understand yet why my app doesn't work correctly.
When a user connects, he have to complete a form. The code for this works. When the user logs out, and then, logs in, the form fields are filled with his information. So, the data is correctly saved. But, when the user changes the form fields values and submits the form, data are not updated.
My model:
class Members(db.Model):
account = db.UserProperty()
hashtags = db.StringProperty()
Here the class to submit the form:
class Submit(webapp.RequestHandler):
def post(self):
user = users.get_current_user()
if user:
url = users.create_logout_url('/')
url_linktext = 'Logout'
member = db.GqlQuery("SELECT * FROM Members WHERE account = :1", user)
if member.count(1) > 0:
m = Members(account=user)
m.hashtags = ','.join([
self.request.get('hashtag1'),
self.request.get('hashtag2'),
self.request.get('hashtag3')])
m.put()
else:
member = Members()
member.account = user
member.hashtags = ','.join([
self.request.get('hashtag1'),
self.request.get('hashtag2'),
self.request.get('hashtag3')])
member.put()
self.redirect('/')
else:
self.redirect('/')
The problem is you are adding a new record instead of updating the existing record. For your code, the simplest fix would be to change this:
if member.count(1) > 0:
m = Members(account=user)
to:
if member.count(1) > 0:
m = member[0]
The reason your code is updating the existing record is because you have not assigned a key. To learn more about keys, you can read about them in Kinds and Identifiers.