Django Friend Request system - python

I am trying to make a friend request system with Django for a cat app, and I am having a problem. I have models to track the friends and the friend request. In the views I have a redirect view with a try except clause that creates a new instance of the friend request model. Then the friend request will be shown to whoever it was sent to, and they will accept or decline it. The problem I have is i don't know how to grab the info about the user to whom the friend request is sent. Any help would be appreciated. Here is the link to my project repository https://github.com/codewiz9/chatter
modles.py
from django.db import models
from django.utils.text import slugify
from django.contrib.auth import get_user_model
User = get_user_model()
# Create your models here.
class Chat(models.Model):
messages = models.TextField(blank=True, max_length=2000, null=False),
date = models.DateTimeField(blank=False, editable=False),
slug = models.SlugField(allow_unicode=True, unique=True,),
friends = models.ManyToManyField(User, through='Friend_List'),
class Friend_List(models.Model):
friend_name = models.ForeignKey(User, related_name='name', on_delete=models.CASCADE),
is_friend = models.BooleanField(default=False),
def __str__(self):
return self.user.username
class Friend_Info(models.Model):
friend_name = models.ForeignKey(User, related_name='name', on_delete=models.CASCADE),
slug = models.SlugField(allow_unicode=True, unique=True,),
class Friend_Request(models.Model):
yes_or_no = models.BooleanField(default=False),
friends = models.ManyToManyField(User, through='Friend_List'),
slug = models.SlugField(allow_unicode=True, unique=True,),
Views.py
from django.shortcuts import render
from django.urls import reverse
from django.views import generic
from .models import Chat, Friend_List, Friend_Info, Friend_Request
# Create your views here.
###Genral###
class Dashbord(generic.TemplateView):
#This classs will have the list of all the users chats
models = Chat, Friend_List
template_name = 'chat_app/dashbord.html'
###Friends###
class Friend_Dashbord(generic.ListView):
#This view will allow users to see thire friends and see thire friend requests and this will contain the button to add new friends
models = Friend_Info, Friend_List
template_name = 'chat_app/friend_dashbord.html'
class Friend_Request(generic.RedirectView):
#This is the form for sending requests S=sent
models = Friend_Request, Friend_list, Friend_Info
def get(self, request, *args, **kwargs):
friend = get_object_or_404(Friend_Info, slug=self.kwargs.get("slug"))
try:
Friend_Request.objects.create(friends=)
class Find_Friends(generic.FormView):
#this will be the page where you can serch for friends
models = Friend
template_name = 'chat_app/dashbord.html'
###Chat###
#the chat portion of the app will be handeled in two parts one will the the form to send the chat and one will be the
#list of all the chats the form view will be inclued on the Chat_list template
class Chat_List(generic.ListView):
#This will be the list of all the chats sent and resived
models = Chat
template_name = 'chat_app/dashbord.html'
class Chat_Form(generic.FormView):
models = Chat
template_name = 'chat_app/dashbord.html'

This is how I would implement such a model:
class FriendRequest(models.Model):
# create a tuple to manage different options for your request status
STATUS_CHOICES = (
(1, 'Pending'),
(2, 'Accepted'),
(3, 'Rejected'),
)
# store this as an integer, Django handles the verbose choice options
status = models.IntegerField(choices=STATUS_CHOICES, default=1)
# store the user that has sent the request
sent_from = models.ForeignKey(User, ..., related_name="requests_sent")
# store the user that has received the request
sent_to = models.ForeignKey(User, ..., related_name="requests_received")
sent_on = models.DateTimeField(... # when it was sent, etc.
Now, you will notice that the two user ForeignKey fields have related_name attributes, these are reverse accessors and are how you can get related model objects.
Say you have a given user object, you can get all of the friend requests they have sent and received using these queries:
# Friend requests sent
user.requests_sent.all()
# Friend requests received from other users
user.requests_received.all()
Those provide you with querysets of other users that you can then iterate over and access as needed.

Related

Django how to write queryset for get all admin user and use them in signals as receiver

My purpose of using django signals is notify every admin when any author create new blog post. So I want to use all admin as a receiver and the only author who creating the blog post will be sender. currently I am using this User.objects.get(username='jhone' )#jhone is an admin user queryset for set receiver specific admin user. How to call all admin user and make theme all as receiver. here is my code:
#models.py
#using notifications model for signals
class Notifications(models.Model):
blog = models.ForeignKey('blog.Blog',on_delete=models.CASCADE)
blogcomment = models.ForeignKey('blog.BlogComment',on_delete=models.CASCADE, blank=True,null=True)
NOTIFICATION_TYPES = (('New Comment','New Comment'),('Comment Approved','Comment Approved'), ('Comment Rejected','Comment Rejected'),('pending post','pending post'),('post approved','post approved'),('post rejected','post rejected'))
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name="noti_from_user")
receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name="noti_to_user")
#others fields......
class Blog(models.Model):
author = models.ForeignKey(User,on_delete=models.CASCADE,max_length=100)
#others fields....
def blog_notify(sender, instance, *args, **kwargs):
blog = instance
blog_title = blog.title
sender = blog.author
receiver = User.objects.get(username='jhone')
if sender == blog.author and blog.is_published == "published":
notify = Notifications(blog=blog, sender=sender,receiver =receiver ,text_preview = blog_title[:250], notification_type="post approved")
notify.save()
post_save.connect(Blog.blog_notify, sender=Blog)
I also tried few queryset for set all admin user as receiver but non of theme didn't work.
receiver = User.objects.all().filter(is_superuser=True)
I am getting this error:
Cannot assign "<QuerySet [<User: Jhone>, <User: admin1>, <User: admin2>]>": "Notifications.user" must be a "User" instance.
for using User.objects.filter(is_superuser=True) this queryset.
I also tried this
receiver = User.objects.all().get(is_superuser=True)
and getting this error
MultipleObjectsReturned at /blog-admin/approve-blog-post/tusar-post2/
get() returned more than one User -- it returned 3!
any idea how to pass right queryset for set all admin user as receiver???
You need to iterate through all the admins and create the Notifications one by one like so:
def blog_notify(sender, instance, *args, **kwargs):
blog = instance
blog_title = blog.title
sender = blog.author
receivers = User.objects.filter(is_superuser=True)
if not (sender == blog.author and blog.is_published == "published"):
return
notifications = []
for receiver in receivers:
notifications.append(Notifications(blog=blog, sender=sender, receiver=receiver, text_preview=blog_title[:250], notification_type="post approved"))
Notifications.objects.bulk_create(notifications)
Just note that if Notifications model is sending signals, then you can't use bulk_create. In that case just create them one by one.

Not able to perform post request django+react

#accounts.models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from words import models as word_models
# Create your models here.class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
last_visited_word = models.ForeignKey(word_models.Word, default=4760, on_delete = models.CASCADE)
def create_user_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User)
#words/models.py
from django.db import models
from django.conf import settings
# Create your models here.
class Word(models.Model):
word = models.TextField(blank=True, null=True)
meaning = models.TextField(blank=True, null=True)
#accounts/serializers.py:
from rest_framework import serializers
from .models import UserProfile
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = '__all__'
#accounts/views.py:
#api_view(['POST'])
##authentication_classes([SessionAuthentication, BasicAuthentication])
#permission_classes([IsAuthenticated])
def userprofile_create_view(request, *args, **kwargs):
user_id = request.data.get('user')
try:
instance = UserProfile.objects.get(user_id=user_id)
except UserProfile.DoesNotExist:
instance=None
serializer = UserSerializer(instance, data=request.data)
if serializer.is_valid(raise_exception=True):
# create or update data
serializer.save()
return Response(serializer.data)
So Basically I have to update the last_visited_word of the user when the user visits that particular id. I am not able to do the "post" method to update last_visited_word. Api calling is done using axios. I am using React as my frontend. When I try to use the post request, it says a bad request. BTW react and django are connected as I am able to do a GET request successfully.
first of the question is kind of incomplete, but from what I can understand you need to configure your settings.py to allow post request from your react localhost. Also finding a way around Django and react can be quite tricky.
check if the api is working as expected. also in the django setting enable cors in middleware and whitelist the server on which the react is running.

django rest api call admin action

i created a simple model and created an admin action for it. Then i installed dango-rest and connected to model so i can use it from another machine with rest api calls. Is there a way i can call the admin action as well?
Here is my sample:
models.py
from django.db import models
class my_model(models.Model):
my_id = models.CharField(primary_key = True, max_length=20)
my_line = models.CharField(max_length=20, default='#')
my_description = models.CharField(max_length=255)
admin.py
from django.contrib import admin, messages
from .models import my_model
def precheck_action(modeladmin, request, queryset):
for obj in queryset:
if obj.my_line == 'second step':
obj.my_description = 'provided'
else:
obj.my_description = 'waithing for second step'
obj.save()
class my_form((forms.ModelForm):
class Meta:
model = int_unmanaged
fields = '__all__'
class my_form_admin(admin.ModelAdmin):
form = my_form
list_display = ('my_id', 'my_line','my_description')
actions = [precheck_action]
admin.site.register(my_form, my_form_admin)
Any help on solving this or maybe a better way of doing it would be great.
Thank!

In Django, how to add creator of a group to that group instantly?

I'm creating a 'social' app in Django, where the users can create groups (Alliances) and others can join these groups. User Profiles and Alliances are connected through Membership model. I´d like the creator of such group to be a member of it instantly.
I'm inexperienced in Django, in fact, this is my first project. But I figured that this maybe could be solved by signals?
My user Profile model:
class Profile(models.Model):
...
user = models.OneToOneField(User, on_delete=models.CASCADE)
alliances = models.ManyToManyField('Alliance', through='Membership')
...
My Alliance model:
class Alliance(models.Model):
...
name = models.CharField(max_length=10, unique=True)
members = models.ManyToManyField('Profile', through='Membership')
...
My Membership model:
class Membership(models.Model):
...
profile = models.ForeignKey('Profile', on_delete=models.CASCADE)
alliance = models.ForeignKey('Alliance', on_delete=models.CASCADE)
...
The solution I figured could work (using signals) would look something like this:
#receiver(post_save, sender=Alliance)
def create_membership(sender, instance, created, **kwargs):
if created:
Membership.objects.create(profile=???, alliance=instance)
Where the '???' should be the creators profile. I'll be really glad for any help.
A signal has no access to the request that triggered it, since it is not said that the trigger is a HTTP request in the first place. You could try to inspect the traceback, but that is a hacky solution that will probably generate more trouble than it is worth.
You will need to do that in the form or in the view where you create the group. For example in the view, you can add this with:
from django.views.generic import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
from app.models import Alliance, Membership
class AllianceCreateView(LoginRequiredMixin, CreateView):
model = Alliance
def form_valid(self, form):
self.object = form.save()
Membership.objects.create(
profile=self.request.user.profile,
alliance=self.object
)
return HttpResponseRedirect(self.get_success_url())
Note that the modeling is quite strange. Normally you do not specify two ManyToManyFields. Django will automatically add the second one. You thus can specify in your Profile:
class Profile(models.Model):
# ...
user = models.OneToOneField(User, on_delete=models.CASCADE)
alliances = models.ManyToManyField(
'Alliance',
through='Membership',
related_name='members'
)

How to notify all users?

I prepared a notification app.
I would like to send a notification to all users.
If I use this line:
user = models.ForeignKey(User)
it creates me a possibility to send a notification to the user which I need to choose. I would like to have an option to send a notification to all of users in the same time
models.py
from django.db import models
from django.contrib.auth.models import User
class Notifications(models.Model):
title = models.CharField(max_length=150, verbose_name="Tytul")
content = models.TextField(verbose_name="Wiadomosci")
viewed = models.BooleanField(default=False, verbose_name="Otwarta")
user = models.ForeignKey(User)
def __unicode__(self):
return self.title
views.py
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from models import Notifications
def show_notification(request, notification_id):
n = Notifications.objects.get(id=notification_id)
return render_to_response('notifications.html',{'notification':n})
def delete_notification(request, notification_id):
n = Notifications.objects.get(id=notification_id)
n.viewed = True
n.save()
return HttpResponseRedirect('/accounts/loggedin')
To add a Notification for each User, here's a solution:
class Notifications(models.Model):
[...]
#classmethod
def notify_all(klass, title, content):
new_notices = list()
for u in User.objects.all():
new_notices.append(klass(user=u, title=title, content=content))
klass.objects.bulk_create(new_notices)
Then, to run this you do:
Notification.notify_all('Test title', 'Test message')
Just iterate over all users and create notification for each of them:
from django.db import transaction
with transaction.atomic():
for user in User.objects.all():
Notifications.objects.create(title="some title", content="some content",
user=user)
As side note: you have a security problem in show_notification() and delete_notification(). You show/delete notification to/by any visitor. Add filter by user like this:
#login_required
def show_notification(request, notification_id):
n = Notifications.objects.get(id=notification_id, user=request.user)
...

Categories