Function notifies commentor when the poster should get notified - python

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.

Related

Django: I get: Cannot query "admin": Must be "Follow" instance in my code when trying to implement unfollow button

I'm a beginner and I'm trying to create a small network project in which users can follow each other. I have implemented the follow button right, so it updates my models and displays proper info to users, but I can't get unfollow to work properly. I'm guessing it's something to do with the way I implemented follow model (with many to many field), but I'd like to implement it this way for practice... Anyhow, here's the code:
Models:
class User(AbstractUser):
pass
class Follow(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_follow")
following = models.ManyToManyField(User, blank=True, related_name="followers")
And view:
def users(request, username):
"""Displaying user profiles"""
if request.method == "POST":
user = request.user
profile = User.objects.get(username=username)
follow = Follow(user=user)
follow.save()
if "unfollow" in request.POST:
profile.followers.remove(user)
follow.following.remove(profile)
return HttpResponseRedirect(reverse('users', args=(username,)))
elif "follow" in request.POST:
follow.following.add(profile)
return HttpResponseRedirect(reverse('users', args=(username,)))
This code yields in: "ValueError at /users/test
Cannot query "admin": Must be "Follow" instance." at the profile.followers.remove(user) line...
Playing with it in shell I found out (at least I think so) that the line under it (follow.following.remove(profile) - which by the way was there before I tried with the profile.followers.remove(user)) removes the profile from Follow model, but for some reason it is not by itself updated in the Users model (for followers) ???
from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=40)
pwd = models.CharField(max_length=40)
def __str__(self):
return self.name
class Follow(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
another_user = models.ManyToManyField(User, related_name='another_user')
def __str__(self):
return self.user.name
============================================================================
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import User, Follow
# Create your views here.
def index(request):
if 'user' in request.session:
return render(request, 'index.html')
else:
return redirect('login')
def profile(request, user_name):
user_obj = User.objects.get(name=user_name)
session_user = User.objects.get(name=request.session['user'])
session_following, create = Followers.objects.get_or_create(user=session_user)
following, create = Followers.objects.get_or_create(user=session_user.id)
check_user_followers = Followers.objects.filter(another_user=user_obj)
is_followed = False
if session_following.another_user.filter(name=user_name).exists() or following.another_user.filter(name=user_name).exists():
is_followed=True
else:
is_followed=False
param = {'user_obj': user_obj,'followers':check_user_followers, 'following': following,'is_followed':is_followed}
if 'user' in request.session:
return render(request, 'profile.html', param)
else:
return redirect('index')
def follow_user(request, user_name):
other_user = User.objects.get(name=user_name)
session_user = request.session['user']
get_user = User.objects.get(name=session_user)
check_follower = Followers.objects.get(user=get_user.id)
is_followed = False
if other_user.name != session_user:
if check_follower.another_user.filter(name=other_user).exists():
add_usr = Followers.objects.get(user=get_user)
add_usr.another_user.remove(other_user)
is_followed = False
return redirect(f'/profile/{session_user}')
else:
add_usr = Followers.objects.get(user=get_user)
add_usr.another_user.add(other_user)
is_followed = True
return redirect(f'/profile/{session_user}')
return redirect(f'/profile/{session_user}')
else:
return redirect(f'/profile/{session_user}')
=============================================================================
User This For Reference...Follow And Unfollw Logic

Django - NOT NULL constraint failed

I'm currently working on a Django app that will parse the contents of an uploaded log file to the associated database in my Django project. I've managed to get it all running as expected except it won't associate my uploaded data with the model's ForeignKey. I can assign null=True which resolves the integrity error but then of course, it doesn't assign any of the uploaded data to that ForeignKey. Here's the code:
models.py
class Case(models.Model):
case_ref = models.CharField(max_length=8)
oic = models.CharField(max_length=50)
subject = models.CharField(max_length=100)
submitted_date = models.DateTimeField(default=datetime.now, blank=True)
def get_absolute_url(self):
return reverse('case_list', kwargs={'pk': self.pk})
def __str__(self):
return self.case_ref + " " + self.subject
class TeamviewerLogs(models.Model):
case = models.ForeignKey(Case, on_delete=models.DO_NOTHING)
teamviewer_id = models.IntegerField()
teamviewer_name = models.TextField()
connection_start = models.TextField()
connection_end = models.TextField()
local_user = models.TextField()
connection_type = models.TextField()
unique_id = models.TextField()
def get_absolute_url(self):
return reverse('case_list', kwargs={'pk': self.pk})
def __str__(self):
return str(self.teamviewer_id) + " - " + str(self.teamviewer_id)
forms.py
class UploadLog(forms.ModelForm):
file = forms.FileField()
class Meta:
model = TeamviewerLogs
fields = [
'file'
]
views.py
def add_logs(request, pk):
case = get_object_or_404(Case, pk=pk)
if request.method == 'POST':
form = UploadLog(request.POST, request.FILES)
if form.is_valid():
teamviewer = form.save(commit=False)
teamviewer.case = case
log_file = request.FILES['file']
log_file = filter(None, (line.rstrip() for line in log_file))
for lines in log_file:
split = lines.decode('utf-8').split('\t')
teamviewer_id = split[0]
teamviewer_name = split[1]
connection_start = split[2]
connection_end = split[3]
local_user = split[4]
connection_type = split[5]
unique_id = split[6]
teamviewer = TeamviewerLogs(teamviewer_id=teamviewer_id, teamviewer_name=teamviewer_name,
connection_start=connection_start, connection_end=connection_end,
local_user=local_user, connection_type=connection_type, unique_id=unique_id)
teamviewer.save()
return redirect('tv_log_details', pk=case.pk)
form.save()
else:
form = UploadLog()
return render(request, 'teamviewer/add_logs.html', {'form': form})
But when I click to upload the file I'm hit with:
When it tries to execute teamviewer.save().
I've been trying to resolve this issue for hours and have tried so many different variations of answers from Stackoverflow or previous code I've used that has worked for different models but I've hit a brick wall...hard!
Any help anyone can offer would be greatly appreciated.
Ok, so here's an example of the concept I've suggested in the comments.
I've got a view which passes some data to the a form;
class ListingDetailView(DetailView):
""" Listing detail page """
model = Listing
template_name = 'listing.html'
def get_form_kwargs(self):
"""Return the kwargs for the form"""
kwargs = {}
initial = {
'listing': self.object,
}
kwargs['initial'] = initial
return kwargs
def get_form(self):
form = ApplicationSignupForm(
**self.get_form_kwargs()
)
return form
def get_context_data(self, **kwargs):
""" Add our form to the context """
context = super().get_context_data(**kwargs)
context['form'] = self.get_form()
return context
The form then makes use of that initial data and sets the field it relates to as hidden. I don't validate this data, but I'll try to show how you might do that;
class ApplicationSignupForm(forms.ModelForm):
class Meta:
""" Setup the form """
fields = (
'listing',
...
)
model = Application
widgets = {
'listing': forms.HiddenInput()
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
initial_data = kwargs['initial']
self.listing = initial_data.get('listing')
def clean(self):
"""
Custom form cleaning
"""
cleaned_data = super().clean()
listing = cleaned_data.get('listing')
if listing != self.listing:
self.add_error('listing', "You can't modify this value")
return cleaned_data

Cannot assign "'7'": "Appointment.your_service" must be a "Service" instance

I'm working on a project "Beauty Parlour Management System" and I got this error (Cannot assign "'7'": "Appointment.your_service" must be a "Service" instance.) anyone here can help me, please.
When I am filling a book appointment form then I got this error.
models.py
class Service(models.Model):
name = models.CharField(max_length=50)
price = models.IntegerField(default=0)
image = models.ImageField(upload_to='uploads/productImg')
class Appointment(models.Model):
your_name = models.CharField(max_length=100)
your_phone = models.CharField(max_length=10)
your_email = models.EmailField(max_length=200)
your_service = models.ForeignKey('Service', on_delete=models.CASCADE, default=1)
your_date = models.DateField()
views.py
def appointments(request):
if request.method == 'GET':
return render(request, 'core/bookappointment.html')
else:
your_name = request.POST.get('your-name')
your_phone = request.POST.get('your-phone')
your_email = request.POST.get('your-email')
your_service = request.POST.get('your-service')
your_date = request.POST.get('your-date')
details = Appointment(
your_name = your_name,
your_phone = your_phone,
your_email = your_email,
your_service = your_service,
your_date = your_date)
details.save()
return render(request, 'core/appointments.html')
You create this by assigining the method to your_service_id field, if you work with your_service, it should be a Service object:
details = Appointment.objects.create(
your_name=your_name,
your_phone=your_phone,
your_email=your_email,
your_service_id=your_service,
your_date=your_date
)
That being said, it is usually better to validate, clean, and save the data with a ModelForm, not manually.
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
def appointments(request,pk):
record = get_object_or_404(Service,pk=pk)
if request.method == 'POST':
form = appointmentsForm(request.POST,request.FILES)
if form.is_valid():
appointment= form.save(commit=False)
appointment.your_service = record
appointment.save()
return render(request, 'core/bookappointment.html')
else:
return render(request, 'core/appointments.html')

Modifying the django-invitations Package to allow Team Functionality

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.

how to fix the 'AnonymousUser' object has no attribute 'profile' error?

I'm writing a chat app for a hypothetical social network but when I try to open the chat page I give the following error 'AnonymousUser' object has no attribute 'profile' error .
I think there may be problem in the models file but I can't really figure out how to fix it and I'm really confused now!? can anyone give any suggestions??
parts of the chat views.py
def index(request):
if request.method == 'POST':
print request.POST
request.user.profile.is_chat_user=True
logged_users = []
if request.user.username and request.user.profile.is_chat_user:
context = {'logged_users':logged_users}
cu = request.user.profile
cu.is_chat_user = True
cu.last_accessed = utcnow()
cu.save()
return render(request, 'djangoChat/index.html', context)
try:
eml = request.COOKIES[ 'email' ]
pwd = request.COOKIES[ 'password' ]
except KeyError:
d = {'server_message':"You are not logged in."}
query_str = urlencode(d)
return HttpResponseRedirect('/login/?'+query_str)
try:
client = Vertex.objects.get(email = eml)
context = {'logged_users':logged_users}
cu = request.user.profile
cu.is_chat_user = True
cu.last_accessed = utcnow()
cu.save()
if client.password != pwd:
raise LookupError()
except Vertex.DoesNotExist:
sleep(3)
d = {'server_message':"Wrong username or password."}
query_str = urlencode(d)
return HttpResponseRedirect('/login/?'+query_str)
return render_to_response('djangoChat/index.html',
{"USER_EMAIL":eml,request.user.profile.is_chat_user:True},
context_instance=RequestContext(request))
#csrf_exempt
def chat_api(request):
if request.method == 'POST':
d = json.loads(request.body)
msg = d.get('msg')
user = request.user.username
gravatar = request.user.profile.gravatar_url
m = Message(user=user,message=msg,gravatar=gravatar)
m.save()
res = {'id':m.id,'msg':m.message,'user':m.user,'time':m.time.strftime('%I:%M:%S %p').lstrip('0'),'gravatar':m.gravatar}
data = json.dumps(res)
return HttpResponse(data,content_type="application/json")
# get request
r = Message.objects.order_by('-time')[:70]
res = []
for msgs in reversed(r) :
res.append({'id':msgs.id,'user':msgs.user,'msg':msgs.message,'time':msgs.time.strftime('%I:%M:%S %p').lstrip('0'),'gravatar':msgs.gravatar})
data = json.dumps(res)
return HttpResponse(data,content_type="application/json")
def logged_chat_users(request):
u = Vertex.objects.filter(is_chat_user=True)
for j in u:
elapsed = utcnow() - j.last_accessed
if elapsed > datetime.timedelta(seconds=35):
j.is_chat_user = False
j.save()
uu = Vertex.objects.filter(is_chat_user=True)
d = []
for i in uu:
d.append({'username': i.username,'gravatar':i.gravatar_url,'id':i.userID})
data = json.dumps(d)
return HttpResponse(data,content_type="application/json")
and parts of my chat models:
class Message(models.Model):
user = models.CharField(max_length=200)
message = models.TextField(max_length=200)
time = models.DateTimeField(auto_now_add=True)
gravatar = models.CharField(max_length=300)
def __unicode__(self):
return self.user
def save(self):
if self.time == None:
self.time = datetime.now()
super(Message, self).save()
def generate_avatar(email):
a = "http://www.gravatar.com/avatar/"
a+=hashlib.md5(email.lower()).hexdigest()
a+='?d=identicon'
return a
def hash_username(username):
a = binascii.crc32(username)
return a
# the problem seems to be here ??!
User.profile = property(lambda u: Vertex.objects.get_or_create(user=u,defaults={'gravatar_url':generate_avatar(u.email),'username':u.username,'userID':hash_username(u.username)})[0])
and finally parts of the another app(ChatUsers):
class Vertex(models.Model,object):
user = models.OneToOneField(User)
password = models.CharField(max_length=50)
#user_id = models.CharField(max_length=100)
username = models.CharField(max_length=300)
userID =models.IntegerField()
Message = models.CharField(max_length=500)
firstname = models.CharField(max_length=50)
lastname = models.CharField(max_length=50)
email = models.EmailField(max_length=75)
is_chat_user = models.BooleanField(default=False)
gravatar_url = models.CharField(max_length=300,null=True, blank=True)
last_accessed = models.DateTimeField(auto_now_add=True)
Because that user has not logged in yet. Django treat them as AnonymousUser and AnonymousUser does not have the profile property.
If the view is only for logged in user, you can add the login_required decorator to the view function to force the login process. Otherwise, you need to judge whether a user is anonymous with the is_authenticated function.
Reference: Using the Django authentication system

Categories