How to create a user to user message system using Django? - python

I am trying to create a private messaging system using Django. It doesn't have to be like a live chat, just have an inbox and be able to respond, simple thing like that. So far, from research I have found two things: django.contrib.messages which doesn't seem to be for private messages, but rather messages from the system to a user. Then I also found django-postman which seems to be what I'm looking for, but there seems to be little documentation on how to use it. So has anybody used anything else to accomplish this? Or am I wrong about django.contrib.messaging? Or is there good documentation on django-postman that I'm missing?

You can create your own custom message app.
Models for Message like app :
Class Message():
Class Message(models.Model):
sender = models.ForeignKey(User, related_name="sender")
reciever = # almost same as above field, just change the related-name
msg_content = # text field
created_at = # time field
Create a form for this model, use model form .
filter "Inbox" queries in views.py by
Message.objects.filter(reciever=request.user)
filter "Sent Box" queries in views.py by
Message.objects.filter(sender = request.user)

There is good documentation on django-postman that you're missing:
https://bitbucket.org/psam/django-postman/wiki/browse/
or
http://django-postman.readthedocs.org/en/latest/

For queries like these, I usually head to Django Packages (https://djangopackages.org/) which lists popular Django packages with comparisons, categorised by the functionality needed.
It has a grid for messaging and based on this grid, django-messages, django-private-chat and django-postman seem to be the top ones.

Related

Connecting my django app to the redis installation

I have a django app. The app is a normal application. Everything is running fine for me.
I want to implement a leaderboard as of now. Read couple of places that redis helps in doing it. And is really awesome. So I installed and configured redis on the server.
A minimal representation of the user profile for me is:
class UserProfile(models.Model):
user = models.OneToOneField(User)
invited_friends = models.BooleanField(default=False)
filled_wishlist = models.BooleanField(default=False)
upvote = models.IntegerField()
downvote = models.IntegerField()
#property
def reputation(self):
return int(confidence_fixed(self.upvote, self.downvote)*100)
Based on this reputation property, I get a value. All this is happening at the PostgreSQL db backend.
Now what I want to do is, take these scores, put them in redis key value store, and generate a leaderboard. There is a superawesome redis library for implementing leaderboard: https://github.com/agoragames/leaderboard-python
So my question is, given my redis server is running say at XXX.XXX.XX.XX:6342
How do I connect my python/django app to the redis server, and update the KV store, and once there are some numbers, how do I fetch in a view and display?
I think you're on the right track with the leaderboard-python library.
First you would need to write a onetime script to move the data from your model to redis using leaderboard-python.
# Create a new leaderboard
reputation_lb = Leaderboard('reputation')
for profile in UserProfile.objects.all():
reputation.rank_member('user_%i' % profile.user.pk, profile.reputation)
You would also need to create another property on the UserProfile model that retrieves the reputation from leaderboard-python.
Then you would most likely want to update the score, either you duplicate the information in the database and continue to use your reputation property to update the leaderboard, or you simply increment/decrement the score stored in redis.
The readme of the leaderboard-python library is quite good and should contain all of the examples you need to build this.
For future googlers, the way to tell Leaderboard how to connect to your redis server is by specifying a few more arguments in the Leaderboard constructor:
reputation_lb = Leaderboard('reputation', host="xyz.com", port="1234")
More details about what options are supported can be found in constructor code for Leaderboard here: http://pydoc.net/Python/leaderboard/2.8.0/leaderboard/

how do i create an admin user in django and link it to a model?

I am modeling a person like so:
class Person(models.Model):
""" Represent a person who has credentials. The person may have
devices and/or accessories. """
#basic information
name = models.CharField(max_length=50, unique=True)
email = models.CharField(max_length=50, unique=True)
phone_number = PhoneNumberField(unique=True)
But I want to be able to add something like:
/* create admin user with a group priveledge*/
user_account = #link to user account here
I'm doing this because as I add people objects, I want them to have an account with certain privelidges.
Thanks to anyone who can help..
It globally depends on the version of Django you're using, since User Models and Inheritance have changed with Django 1.5.
You might want to take a look at the Django Official Documentation : https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
Cheers,
K.
EDIT 19:30 CEST : You should be taking care of the switch in the right top of the Django's Documentation website, just to be sure you're looking at the right documentation (i.e. the documentation that concerns the Django's version you're using). As from 1.5, Django added an awesome thing : not just "relate" to the User model, but also Extends it. https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model .
And, as I guess that you want to add user via the automatic admin, you should take care of this paragraph too : https://docs.djangoproject.com/en/dev/topics/auth/customizing/#custom-users-and-django-contrib-admin
The only thing is that you must run Django 1.5+ to do that. Django 1.4 and lesser just let you add a related model, wich is not so bad yet :).
Can we say that what you want is just a User with a few more informations ?
Or is there a situation where you'll say
"A person may not be a user" and/or
"A user may not be a person"
What you describe here is possible with the simple system of the foreign key. Make a new model Person like this :
class Person(models.Model):
... some infos here ...
user = model.ForeignKey(User)
And then, you'll just have to create the User and then, the Person. There's many ways you can tell Django to create automatically the Person object when the User object is created. This blogpost could drive you the right way : http://www.turnkeylinux.org/blog/django-profile
Maybe you should follow it, and then explain us exactly what you miss ?
Cheers, again.
K.

How do I inform a user if an event has been created by the admin in Django? [duplicate]

This question already has answers here:
Facebook like notification updates using django signal or notification
(2 answers)
Closed 9 years ago.
We're currently developing a system for a certain organization. One of the requirement is to inform users whenever the admin creates an event. All the site users should be notified not through e-mail but something similar to Facebook notification. How do I implement such feature in Django without using Django-notifications, Django-activity streams, etc. We're newbies to Django and we wanted to implement such feature as simple as it can be. I hope you can help us with this matter. Thank you all!
So, I can really only give you some general direction, as I don't know the particulars, but basically you could do something like this:
First, I would add an override to the save_model() method of your admin class. This is where you can check to see if your object has a primary key yet. If not, you can set a flag to create the event (not sure if you need to also associate your event to the notification via a foreign key.
If you don't need to have an association between your Event and the notification, you could skip setting a flag and just create the notification object whenever you want.
Second, create a view that returns JSON for your events. I'm not sure how you would need to filter these objects. Is it only for logged in users, etc, but you would only want to return ones that have not been previously viewed.
Third, call the view via ajax on an interval, passing in whatever criteria you need to filter the results and record the notification has been viewed.
Hope that gets you going.
#Zayatzz we're planning on notifying the users once. But after the
user viewed the notification, he/she can still view it later on.
In this case you probably need to create notification objects in the admin. Object probably needs to be something like this:
class Notification(models.Model):
message = models.TextField()
type = models.IntegerField()
relevancy_end_date = models.DateField()
notified_users = models.ManyToManyField(django.contrib.auth.User, null = True)
In your admin form you need to override that models.IntegerField to have widget with choices. The choices you can get from :
https://docs.djangoproject.com/en/dev/ref/contrib/messages/#creating-custom-message-levels
They are basically numbers, 10, 20, 30, 40, 50.
In view you can check if there are notifications that user should be notified of:
notes = Notification.objects.filter(notified_users__id = request.user.id).filter(relevancy_end_date__gte = datetime.datetime.now())
And if there are any notifications, create messages of those using djanogs own message framework:
from django.contrib import messages
if notes:
for note in notes:
messages.add_message(request, note.type, 'Hello world.')
note.notified_users.add(request.user)
what type of message it is (info, error, success) is saved in your notifications type column. so yes - you need to add some kind of check there that varies message type based on notification type.
Its not very DRY to write that block into the beginning of each view where you want to display messages though. So you should create your own view decorator for that.
These 2 links should help you do that:
https://docs.djangoproject.com/en/dev/topics/http/decorators/
How create decorator in Django for decorating view
Now at this point. If there is message that user needs to be notified of - it is in request handled by messages framework. And to display it in view you need to do this:
https://docs.djangoproject.com/en/dev/ref/contrib/messages/#displaying-messages
OR. Like Brandon says- if you want messages to delivered by ajax/json calls also, then you need to "manually" handle them and insert them into json responses. Something like this:
https://docs.djangoproject.com/en/dev/ref/contrib/messages/#expiration-of-messages
from django.utils import simplejson
feedback = messages.get_messages(request)
for message in feedback:
response[message.tags] = response.get(message.tags, [])
message_text = smart_str(message.message, encoding='utf-8', strings_only=True)
response[message.tags].append(message_text)
return simplejson.dumps(response)
After you have Notification object, have your view decorator then you only need to create a view for displaying user the notifications he has been shown. I'm sure you can figure out how to create that query.
You can also tweak this Notification class to have extra boolean field instead or with relevancy_end_date field. To make turning it on or off easyer.
NB! This code is completely untested and will probably give out some errors, but its something to get you going in the direction, that i thought might be best for you judging by your input.
Alan

how to overwrite User model

I don't like models.User, but I like Admin view, and I will keep admin view in my application.
How to overwirte models.User ?
Make it just look like following:
from django.contrib.auth.models import User
class ShugeUser(User)
username = EmailField(uniqute=True, verbose_name='EMail as your
username', ...)
email = CharField(verbose_name='Nickname, ...)
User = ShugeUser
That isn't possible right now. If all you want is to use the email address as the username, you could write a custom auth backend that checks if the email/password combination is correct instead of the username/password combination (here's an example from djangosnippets.org).
If you want more, you'll have to hack up Django pretty badly, or wait until Django better supports subclassing of the User model (according to this conversation on the django-users mailing list, it could happen as soon as Django 1.2, but don't count on it).
The answer above is good and we use it on several sites successfully. I want to also point out though that many times people want to change the User model they are adding more information fields. This can be accommodated with the built in user profile support in the the contrib admin module.
You access the profile by utilizing the get_profile() method of a User object.
Related documentation is available here.

Django Project structure, recommended structure to share an extended auth "User" model across apps?

I'm wondering what the common project/application structure is when the user model extended/sub-classed and this Resulting User model is shared and used across multiple apps.
I'd like to reference the same user model in multiple apps.
I haven't built the login interface yet, so I'm not sure how it should fit together.
The following comes to mind:
project.loginapp.app1
project.loginapp.app2
Is there a common pattern for this situation?
Would login best be handled by a 'login app'?
Similar to this question but more specific.
django application configuration
UPDATE
Clarified my use-case above.
I'd like to add fields (extend or subclass?) to the existing auth user model. And then reference that model in multiple apps.
Why are you extending User? Please clarify.
If you're adding more information about the users, you don't need to roll your own user and auth system. Django's version of that is quite solid. The user management is located in django.contrib.auth.
If you need to customize the information stored with users, first define a model such as
class Profile(models.Model):
...
user = models.ForeignKey("django.contrib.auth.models.User", unique=True)
and then set
AUTH_PROFILE_MODULE = "appname.profile"
in your settings.py
The advantage of setting this allows you to use code like this in your views:
def my_view(request):
profile = request.user.get_profile()
etc...
If you're trying to provide more ways for users to authenticate, you can add an auth backend. Extend or re-implement django.contrib.auth.backends.ModelBackend and set it as
your AUTHENTICATION_BACKENDS in settings.py.
If you want to make use of a different permissions or groups concept than is provided by django, there's nothing that will stop you. Django makes use of those two concepts only in django.contrib.admin (That I know of), and you are free to use some other concept for those topics as you see fit.
You should check first if the contrib.auth module satisfies your needs, so you don't have to reinvent the wheel:
http://docs.djangoproject.com/en/dev/topics/auth/#topics-auth
edit:
Check this snippet that creates a UserProfile after the creation of a new User.
def create_user_profile_handler(sender, instance, created, **kwargs):
if not created: return
user_profile = UserProfile.objects.create(user=instance)
user_profile.save()
post_save.connect(create_user_profile_handler, sender=User)
i think the 'project/app' names are badly chosen. it's more like 'site/module'. an app can be very useful without having views, for example.
check the 2008 DjangoCon talks on YouTube, especially the one about reusable apps, it will make you think totally different about how to structure your project.

Categories