user profile of other user shows up - python

The id of admin is 1 when i open the admin user at the admin panel. Likewise the id of michael is 2 but when i click the profile icon instead of showing me the profile of admin i get profile of michael. To get the id i have used user.id of the requested user.
Also the problem is i could not use slug in such model.
restaurant/base.html
{% if user.is_authenticated %}
<li class="nav-item">
<a class="nav-link user-icon" href="{% url 'userprofiles:profile' user.id %}">
<i class="fa fa-user"></i>
</a>
</li>
{% else %}
userprofiles/urls.py
urlpatterns = [
# url(r'^profile/(?P<profile_name>[-\w]+)/(?P<profile_id>\d+)/$', views.profile, name='profile'),
url(
r'^profile/(?P<profile_id>\d+)/$',
views.profile,
name='profile'
),
]
userprofiles/views.py
def profile(request, profile_id):
if profile_id is "0":
userProfile = get_object_or_404(UserProfile, pk=profile_id)
else:
userProfile = get_object_or_404(UserProfile, pk=profile_id)
user_restaurant = userProfile.restaurant.all()
user_order = userProfile.order_history.all()
total_purchase = 0
for ur in user_order:
total_purchase += ur.get_cost()
return render(
request,
'userprofiles/profile.html',
{
'userProfile':userProfile,
'user_restaurant':user_restaurant,
'user_order':user_order,
'total_purchase':total_purchase
}
)
userprofiles/profile.html
{% for user_restaurant in user_restaurant %}
{{user_restaurant.name}}<br/>
{{user_restaurant.address }}
{% endfor %}
userprofiles/models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
restaurant = models.ManyToManyField(Restaurant)
order_history = models.ManyToManyField(OrderMenu)
# favorites = models.ManyToManyField(Restaurant)
is_owner = models.BooleanField(default=False)
class Meta:
def __str__(self):
return self.user.username
# def get_absolute_url(self):
# return reverse('userprofiles:profile', kwargs={'slug':self.slug, 'id':self.id})
How can i use slug for such model so that in admin panel the slug for that user be automatically saved? Because there is no post method.
But the main problem is i am getting userprofile of another user.

Just add 1 everywhere you use profile_id
def profile(request, profile_id):
if profile_id is "0": # Is profile_id a string or integer?
userProfile = get_object_or_404(UserProfile, pk=(profile_id+1)) # What does this do?
else:
userProfile = get_object_or_404(UserProfile, pk=(profile_id+1))
user_restaurant = userProfile.restaurant.all()
user_order = userProfile.order_history.all()
total_purchase = 0
for ur in user_order:
total_purchase += ur.get_cost()
return render(request, 'userprofiles/profile.html', {'userProfile':userProfile,
'user_restaurant':user_restaurant,
'user_order':user_order,
'total_purchase':total_purchase })
I suspect that somewhere in your code you've got a n-1 problem (i.e. computers start counting at 0 but humans start counting at 1). I haven't found exactly where it is, but this will probably work as a bandage solution in the meantime.
Also, I'm not sure what that if does in your code, it looks like it would never get used if profile_id is an integer.

I used slug instead of id and for using slug i have used pre_save signal where slug value is taken from the username.
def profile(request, profile_slug):
if profile_slug is None:
userprofile = get_object_or_404(UserProfile,slug=profile_slug)
else:
userprofile = get_object_or_404(UserProfile, slug=profile_slug)
user_restaurant = userprofile.restaurant.all()
user_order = userprofile.order_history.all()
total_purchase = userprofile.total_purchase
return render(request, 'userprofiles/profile.html', {'userprofile':userprofile,
'user_restaurant':user_restaurant,
'user_order':user_order,
'total_purchase':total_purchase})
I filled the value of slug in this way.
def create_slug(instance, new_slug=None):
print('instance',instance.user)
slug = slugify(instance.user.username)
if new_slug is not None:
slug = new_slug
qs = UserProfile.objects.filter(slug=slug).order_by("-id")
exists = qs.exists()
if exists:
new_slug = "%s-%s" %(slug, qs.first().id)
return create_slug(instance, new_slug=new_slug)
return slug
def pre_save_post_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = create_slug(instance)
from django.db.models.signals import pre_save
pre_save.connect(pre_save_post_receiver, sender=UserProfile)

Related

How can i call a list in django template?

Here is my models.py file.
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.text import slugify
import misaka
from django.contrib.auth import get_user_model
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=255, unique=True)
slug = models.SlugField(allow_unicode=True, unique=True)
description = models.TextField(blank=True, default='')
description_html = models.TextField(editable=False, default='',blank=True)
members = models.ManyToManyField(User, through="CategoryMember")
category_pic = models.ImageField(upload_to = 'category_pics', blank=True)
def __str__(self):
return self.name
# WE are saving the model. But before that we are converting
# the name using slugify and description using misaka.
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
self.description_html = misaka.html(self.description)
super().save(*args, **kwargs)
#get_absolute_url is used because it tell the template
# CreateView to go to the page it is directing.
# for this example it is directing to go to single page of a category.
def get_absolute_url(self):
return reverse("categories:single", kwargs={"slug":self.slug})
class Meta:
ordering = ['name']
class CategoryMember(models.Model):
category = models.ForeignKey(Category, related_name = "memberships", on_delete=models.CASCADE)
user = models.ForeignKey(User, related_name="user_categories", on_delete=models.CASCADE)
def __str__(self):
return self.user.username
class Meta:
unique_together= ("category", "user")
This is some part of views.py file
from django.contrib.auth.models import User
from categories.models import CategoryMember, Category
class UserPosts(ListView):
model = Post
template_name = 'posts/user_post_list.html'
def get_queryset(self):
try:
self.post_user = User.objects.prefetch_related("user_of_post_model").get(
username__iexact=self.kwargs.get("username")
)
except User.DoesNotExist:
raise Http404
else:
return self.post_user.user_of_post_model.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
current_user = UserProfileInfo.objects.filter(
user__id__iexact = self.post_user.id
).get()
i=1
user_categories={}
for member in CategoryMember.objects.all():
if member.user == self.post_user:
user_categories.update({i:member.category.name})
i=i+1
else:
print('not found')
print(user_categories)
if current_user.profile_pic:
profile_pic = True
picture = current_user.profile_pic
edited_picture = get_thumbnail(picture, '350x350', quality=99, format='PNG')
else:
profile_pic = False
root = settings.MEDIA_ROOT
import os
root1 = os.path.join(root, 'profile_pics/no-image.png')
picture = root1
edited_picture = get_thumbnail(picture, '350x350', quality=99, format='PNG')
# resizeimage.resize_cover(picture, [200, 100], validate=False)
# rescale_image(picture,width=100,height=100)
current_user1 = current_user
user_info = {
'current_user':current_user,
'user_categories':user_categories,
'picture':edited_picture,
'profile_pic':profile_pic,
'post_user':self.post_user,
}
context['user_info'] = user_info
return context
After rendering the html page i can see that dictionary has values inside. Here is the values printed in terminal.
not found
not found
not found
not found
not found
{1: 'Regression', 2: 'Classification'}
Now, i want to get user_categories in my django template. i have tried in different approaches but can't get user_categories .
this is some part of my django html file.
<h3>Member of Categories</h3>
{# this line shows error #}
{# {{ userinfo[{{user_categories}}] }} #}
{{ userinfo.user_categories.1 }}
{% for categories in userinfo.user_categories %}
{{categories}}
{% endfor %}
<h5 class="techfont">Post written by {{user_info.post_user.username}} : {{post_list.count}} </h5>
This section only renders user_info.post_user.username but not user_info.user_categories.1
see the text below.
Member of categories.
Post written by abc: 1
user_categories is a dictionary, not a list. So try like this:
{% for idx, categories in userinfo.user_categories.items %}
{{idx}}. {{categories}}
{% endfor %}

Like button in django is not working properly in django

I have added like and dislike button to Song post When like object is not created if some click on like it is showing intigrity error if like object is already there then it is not rendering that to template.
models.py
Codes in models.py
class Song(models.Model):
song_title = models.CharField(max_length=25)
album = models.ForeignKey(Album, related_name='album_name', on_delete=models.CASCADE, blank=True)
singer = models.ManyToManyField(Singer, blank=True)
language = models.CharField(max_length=25)
class VoteManager(models.Manager):
def get_vote_or_unsaved_blank_vote(self,song,user):
try:
return Vote.objects.get(song=song,user=user)
except ObjectDoesNotExist:
return Vote(song=song,user=user)
class Vote(models.Model):
UP = 1
DOWN = -1
VALUE_CHOICE = ((UP, "👍️"),(DOWN, "👎️"),)
like = models.SmallIntegerField(choices=VALUE_CHOICE)
user = models.ForeignKey(User,on_delete=models.CASCADE)
song = models.ForeignKey(Song, on_delete=models.CASCADE)
voted_on = models.DateTimeField(auto_now=True)
objects = VoteManager()
class Meta:
unique_together = ('user', 'song')
views.py
Codes in views.py
class SongDetailView(DetailView):
model = Song
template_name = 'song/song_detail.html'
def get_context_data(self,**kwargs):
ctx = super().get_context_data(**kwargs)
if self.request.user.is_authenticated:
vote = Vote.objects.get_vote_or_unsaved_blank_vote(song=self.object, user = self.request.user)
if vote.id:
vote_url = reverse('music:song_vote_update', kwargs={'song_id':vote.song.id,'pk':vote.id})
else:
vote_url = reverse('music:song_vote_create', kwargs={'song_id':vote.song.id})
vote_form = SongVoteForm(instance=vote)
ctx['vote_form'] = vote_form
ctx['vote_url'] = vote_url
return ctx
class SongUpdateView(UpdateView):
form_class = SongVoteForm
queryset = Song.objects.all()
def get_object(self,queryset=None):
song = super().get_object(queryset)
user = self.request.user
return song
def get_success_url(self):
song_id = self.kwargs.get('song_id')
return reverse('music:song_detail', kwargs={'pk':song_id})
class SongVoteCreateView(View):
form_class = SongVoteForm
context = {}
def post(self,request,pk=None,song_id=None):
vote_obj,created = Vote.objects.get_or_create(pk=pk)
song_obj = Song.objects.get(pk=song_id)
vote_form = SongVoteForm(request.POST, instance=vote_obj)
if vote_form.is_valid():
new_vote = vote_form.save(commit=False)
new_vote.user = self.request.user
new_vote.song = song_obj
return redirect('/album/')
Song_detail.html
codes in song_detail.html
<form action="{{vote_url}}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ vote_form.as_p }}
<button class="btn btn-primary" type="submit" >Vote</button>
</form>
Error Code
This is the error when submitting the like button. Refer here for the traceback
NOT NULL constraint failed: album_vote.song_id
song and user fields are required. So you have to give song and user while creating Vote.
here is full code::
class SongVoteCreateView(View):
form_class = SongVoteForm
context = {}
def post(self,request,pk=None,song_id=None):
song_obj = Song.objects.get(pk=song_id)
vote_obj,created = Vote.objects.get_or_create(song = song_obj, user = request.user)
vote_form = SongVoteForm(request.POST, instance=vote_obj)
if vote_form.is_valid():
vote_form.save()
return redirect('/album/')
also in VoteManager, the code
return Vote(song=song,user=user)
won't create vote, instead you have to use
return Vote.objects.create(song=song,user=user)

Can't Add/Accept and Decline/Cancel Friend requests on Django

Able to Send Friend requests successfully but responding to the requests are an issue. When you press Accept to Add, the button is removed but the Friend isn't added or when you press Cancel to Decline, nothing happens.
Tried adding a forms
class Add_Friend(forms.ModelForm):
model = UserProfile
def add_friend(request, user_profile):
request.notification_set.get(type=Notification.FRIEND_REQUEST, sender=user_profile.user.username).delete()
request.friends.add(user_profile)
user_profile.friends.add(self)
request.friend_requests.remove(user_profile)
noti = Notification.objects.create(owner=user_profile, type=Notification.ACCEPTED_FRIEND_REQUEST, sender=self.user.username)
user_profile.notification_set.add(noti)
return self.friends.count()
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(blank=True, max_length=128)
friends = models.ManyToManyField('self', blank=True, related_name='friends')
friend_requests = models.ManyToManyField('self', blank=True, related_name='friend_requests')
def send_friend_request(self, user_profile):
self.friend_requests.add(user_profile)
noti = Notification.objects.create(owner=self, type=Notification.FRIEND_REQUEST, sender=user_profile.user.username)
self.notification_set.add(noti)
return self.friend_requests.count()
def add_friend(self, user_profile):
self.friend_requests.remove(user_profile)
self.notification_set.get(type=Notification.FRIEND_REQUEST, sender=user_profile.user.username).delete()
self.friends.add(user_profile)
user_profile.friends.add(self)
noti = Notification.objects.create(owner=user_profile, type=Notification.ACCEPTED_FRIEND_REQUEST, sender=self.user.username)
user_profile.notification_set.add(noti)
return self.friends.count()
def cancel_friend_request(self, user_profile):
self.friend_requests.remove(user_profile)
self.notification_set.get(type=Notification.FRIEND_REQUEST, sender=user_profile.user.username).delete()
noti = Notification.objects.create(owner=user_profile, type=Notification.DECLINED_FRIEND_REQUEST, sender=self.user.username)
user_profile.notification_set.add(noti)
return self.friend_requests.count()
def __str__(self):
return self.get_first_name()
#Takes you to the userprofile page
def get_absolute_url(self):
return "/users/{}".format(self.id)
#method_decorator(login_required, name='dispatch')
class SendFriendRequestView(View):
def get(self, request, *args, **kwargs):
profile_id = request.GET.get('profile_id')
requester_id = request.GET.get('requester_id')
target = UserProfile.objects.get(id=profile_id)
requester = UserProfile.objects.get(id=requester_id)
target.send_friend_request(requester)
message = 'Friend request to {} sent!'.format(target.visible_name)
messages.info(request, message)
return redirect('profile', username=target.user.username)
#method_decorator(login_required, name='dispatch')
class CancelFriendRequestView(View):
def cancel_friend_request(request, id):
if request.user.is_authenticated():
user = get_object_or_404(User, id=id)
frequest, created = FriendRequest.objects.filter(
from_user=request.user,
to_user=user).first()
frequest.delete()
return HttpResponseRedirect('/users')
#method_decorator(login_required, name='dispatch')
class AddFriendView(View):
def get(self, request, *args, **kwargs):
try:
profile_id = request.GET.get('profile_id')
requester_id = request.GET.get('requester_id')
target = UserProfile.objects.get(id=profile_id)
requester = UserProfile.objects.get(id=requester_id)
target.add_friend(requester)
message = 'Added friend {}!'.format(target.visible_name)
messages.info(request, message)
return redirect('friends', username=target.user.username)
except Exception as e:
print('Error: {}'.format(e))
url(r'^friend-request/send/(?P<id>[\w\-]+)/$', send_friend_request),
url(r'^friend-request/cancel/(?P<id>[\w\-]+)/$', cancel_friend_request),
url(r'^friend-request/accept/(?P<id>[\w\-]+)/$', accept_friend_request),
{% if user.userprofile in userprofile.friends.all %}
<form>
<button id="remove_friend" data-requesterid="{{user.userprofile.id}}" data-profileid="{{userprofile.id}}">
Remove friend
</button>
</form>
{% elif user.userprofile in userprofile.friend_requests.all %}
Friend request pending...
<form>
<button id="cancel_friend_request " data-requesterid="{{user.userprofile.id}}" data-profileid="{{userprofile.id}}">
Cancel
</button>
</form>
{% else %}
<form>
<button id="send_friend_request" data-requesterid="{{user.userprofile.id}}" data-profileid="{{userprofile.id}}">
Send friend request
</button>
</form>
{% endif %}
I'd like the User to be able to Accept/Decline Friend Requests.

Pre-populating a child models django create form with a parent's ID

I have followed the guidelines from This answer in order to pass Parent pk to the child creation page. At the moment though it is not working and I am seeing the following log.
[14/Jul/2017 13:15:37] "POST /catalog/productstatus/2/create/ HTTP/1.1" 200 4001
I'm not sure what I'm doing wrong, here is the code I currently have.
Models
Models.py
class Product(models.Model):
serial_number = models.CharField(unique=True, max_length=15)
class ProductStatus(models.Model):
serial_number = models.ForeignKey('Product', on_delete=models.CASCADE, null=True)
status = models.CharField(max_length=20, blank=True, default='Stock', help_text='Products status')
date = models.DateTimeField(auto_now_add=True)
View
class ProductStatusCreate(CreateView):
model = ProductStatus
template_name = 'catalog/productstatus_create.html'
form_class = ProductStatusModelForm
def form_valid(self, form):
productstatus = form.save(commit=False)
product_id = form.data['product_id']
product = get_object_or_404(Product, id=product_id)
productstatus.product = product
return super(ProductStatusCreate, self).form_valid(form)
def get_context_data(self, **kwargs):
context = super(ProductStatusCreate, self).get_context_data(**kwargs)
context['s_id'] = self.kwargs['product_id']
return context
def get_success_url(self):
if 'product_id' in self.kwargs:
product = self.kwargs['product_id']
else:
product = self.object.product.pk
return reverse_lazy('product_detail', kwargs={'pk': product})
Forms
class ProductStatusModelForm(forms.ModelForm):
class Meta:
model = ProductStatus
fields = ['status',]
def __init__(self, *args, **kwargs):
self.fields["product"] = forms.CharField(widget=forms.HiddenInput())
super(ProductStatusModelForm, self).__init__( *args, **kwargs)
templates/myapp/product_detail.html
New
urls.py
urlpatterns += [
url(r'^productstatus/(?P<product_id>\d+)/create/$', views.ProductStatusCreate.as_view(), name='productstatus_create'),
]
productstatus_create.html
{% extends "base_generic.html" %}
{% block content %}
<h2>New Product Status</h2>
</br>
<form action="" method="post">
{% csrf_token %}
<table>
<input type=hidden id="id_product" name="product" value="{{ s_id }}">
{{ form }}
</table>
<input type="submit" value="Submit" />
</form>
</br>
{% endblock %}
When looking at the page's source the value does get populated but when I submit the form nothing happens.
Why do you have views.ProductInstanceCreate.as_view() in your urls.py but the view you show is called ProductStatusCreate? Are you sure you are using the right view?
You are creating a 'product' hidden field in your form, but not providing a value for it anywhere. Your template output then has two product fields, and the latter (blank) is taken, so returns an error saying it is required.
None of this outputting the product ID to the template in order to read it back in is necessary - you always have the ID available to you in the URL kwargs.
You can get rid of your get_context_data, and the extra field code in the Form and template. Your form_valid can be something like:
def form_valid(self, form):
product = get_object_or_404(Product, id=self.kwargs['product_id'])
form.instance.product = product
return super().form_valid(form)
And product_id will always be in self.kwargs, so your get_success_url can be shorter too:
def get_success_url(self):
product = self.kwargs['product_id']
return reverse('product_detail', kwargs={'pk': product})

How to follow on a button click in Django?

Views.py - I want to be able to go to a users page, and then click and follow them from a button exactly like twitter, i sort of know how to add users as you can see by my add variable in my view but I really have not clue how to actually implement that into a button that allows me to follow the user! I have been stuck on this for a whole day and it may be very obvious so any help is greatly appreciated! I do not think my template is need for this question but if it is let me know!
#login_required
def home(request, username):
context = {}
if username == request.user.username:
return HttpResponseRedirect('/home /user/{0}'.format(request.user.username))
else:
user = User.objects.get(username=username)
user_profile = UserProfile.objects.filter(user=user)
following = user.userprofile.follows.all()
number = user.userprofile.follows.all().count()
tweet = Tweet.objects.filter(userprofile=user_profile).order_by('date')
yum = Tweet.objects.filter(userprofile=user_profile).count()
add = user.userprofile.follows.add(request.user.userprofile)
context['user'] = user
context['profile'] = user_profile
context['follow'] = following
context['number'] = number
context['tweet'] = tweet
context['yum'] = yum
return render (request, 'homer.html', context)
models.py
from django.db import models
from django.contrib.auth.models import User
import os
def get_image_path(instance, filename):
return os.path.join('photos', str(instance.user.id), filename)
class UserProfile(models.Model):
user = models.OneToOneField(User)
bio = models.CharField(max_length=120, blank=True, verbose_name='Biography')
follows = models.ManyToManyField('self', related_name='followers', symmetrical=False, blank=True)
theme = models.ImageField(upload_to=get_image_path, blank=True)
profile_picture = models.ImageField(upload_to=get_image_path, blank=True)
def __str__(self):
return self.bio
class Tweet(models.Model):
userprofile = models.ForeignKey(UserProfile)
tweets = models.TextField(max_length=120)
date = models.DateTimeField()
def __str__(self):
return self.tweets
You could do this on a GET or a POST. Here's the view it on a GET since that's simpler.
from django.http import JsonResponse
def follow_user(request, user_profile_id):
profile_to_follow = get_object_or_404(UserProfile, pk=user_profile_id)
user_profile = request.user.userprofile
data = {}
if profile_to_follow.follows.filter(id=user_profile.id).exists():
data['message'] = "You are already following this user."
else:
profile_to_follow.follows.add(user_profile)
data['message'] = "You are now following {}".format(profile_to_follow)
return JsonResponse(data, safe=False)
Then in your urls.py you'd need to add the following to your urlpatterns.
url(r'^follow/(?<user_profile_id>[\d]+)/$', views.follow_user)
Then you'd need to use some javascript like the following:
$('.follow-button').click(function() {
$.get($(this).data('url'), function(response) {
$('.message-section').text(response.message).show();
});
});
This assumes some html like the following:
<body>
<div class="message-section" style="display:none;"></div>
{% for user_profile in all_user_profiles %}
<button data-url="{% url "example_app.views.follow_user" user_profile_id=user_profile.id %}"
class="follow-button" type="button">Follow</button>
{% endfor %}
</body>

Categories