how can I access userprofile from another user? - django

I need some help when I create a user and user profile accordingly and when I try to access to any user by another user the request turns me on the request I work on not the real user, although, I'm using the slug to specify what the user I click on it maybe I can not explain what happens to me exactly for more explanation, please click on that video to show what I mean: https://www.youtube.com/watch?v=MzSo0ay2_Xk&feature=youtu.be
accounts app
models.py
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.template.defaultfilters import slugify
CHOICE = [('male', 'male'), ('female', 'female')]
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
slug = models.SlugField(max_length=100, unique=True, blank=True)
overview = models.TextField(editable=True, blank=True, default='You have no an Overview yet')
city = models.CharField(max_length=20, blank=False)
phone = models.IntegerField(default=0, blank=True)
sex = models.CharField(max_length=10, default='male', choices=CHOICE)
skill = models.CharField(max_length=100, default='You have no skills yet')
logo = models.ImageField(upload_to='images/', default='images/default-logo.jpg', blank=True)
def __str__(self):
return self.user.username
def save(self, *args, **kwargs):
self.slug = slugify(self.user)
super().save(*args, **kwargs)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(receiver=create_profile, sender=User)
view.py
class ViewProfile(UpdateView):
queryset = UserProfile.objects.all()
template_name = 'accounts/profile.html'
form_class = UpdateInfoForm
slug_field = 'slug'
slug_url_kwarg = 'user_slug'
def get_success_url(self):
return reverse_lazy('accounts:view_profile', kwargs={'user_slug': self.request.user.userprofile.slug})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user_prof = UserProfile.objects.get(user=self.request.user)
context['user_prof'] = user_prof
context['get_favourite'] = User.objects.get(username=self.request.user.username).favorite.all()
return context
def form_valid(self, form):
form.instance.user_slug = self.request.user.userprofile.slug
self.object = form.save()
return super().form_valid(form)
profile.html
{% extends 'base.html' %}
{% block title %} {{ user.first_name }} {{ user.last_name }} Profile {% endblock %}
{% block body %}
<!-- User Profile Section -->
{% if user.is_authenticated %}
<div class="profile">
<div class="container-fluid">
<div class="col-md-1">
<div class="thumbnail">
<div class="row">
<div class="col-xs-12">
<!-- Profile View Section -->
<div class="logo-image text-center">
{% if user.userprofile.logo %}
<div class="my-image">
{% if request.user.username == user.userprofile.slug %}
<a href="{% url 'accounts:user_image' user.userprofile.slug %}">
<img class="img-responsive" src="{{ user.userprofile.logo.url }}">
</a>
<span>
<a href="{% url 'accounts:add_avatar' user.userprofile.slug %}" class="fa fa-camera fa-1x text-center">
<p>Upload Image</p>
</a>
</span>
{% endif %}
</div>
{% else %}
{% load static %}
<div class="my-image">
<img class="img-responsive img-thumbnail" src="{% static 'index/images/default-logo.jpg' %}">
<span>
<a href="{% url 'accounts:add_avatar' user.userprofile.slug %}" class="fa fa-camera fa-1x text-center">
<p>Upload Image</p>
</a>
</span>
</div>
{% endif %}
<h4>{{ user.first_name }} {{ user.last_name }}</h4>
</div>
</div>
<div class="col-xs-12">
<div class="caption">
<ul class="nav nav-pills nav-stacked">
<li role="presentation" class="active">Overview</li>
<li role="presentation" class="">Personal Information</li>
<li role="presentation" class="">Skills</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Information Sections -->
<div class="col-md-8 col-md-offset-3 information">
<div class="overview show" id="overview">
<h2 class="line">Overview</h2>
<p class="lead">{{ user.userprofile.overview }}</p>
<a data-placement="bottom" title="update overview" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".overview_info"></a>
</div>
<div class="personal-info" id="personal-information">
<h2 class="line">Personal Information</h2>
<p class="lead">City: {{ user.userprofile.city }}</p>
<p class="lead">Phone Number: 0{{ user.userprofile.phone }}</p>
<p class="lead">Sex: {{ user.userprofile.sex }}</p>
<a data-placement="bottom" title="update personal information" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".personal_info"></a>
</div>
<div class="skill" id="my-skills">
<h2 class="line">Skills:</h2>
<p class="lead">{{ user.userprofile.skill }}</p>
<a data-placement="bottom" title="update skills" class="fa fa-edit" data-toggle="modal" data-tooltip="tooltip" data-target=".skills"></a>
</div>
</div>
<!-- get all questions -->
{% if user_prof.userasking_set.all %}
<div class="col-md-8 col-md-offset-3 user_questions">
<h2 class="line">All Questions You Asked</h2>
{% for questions in user_prof.userasking_set.all %}
<p>{{ questions.title }}</p>
{% endfor %}
</div>
{% endif %}
<!-- get favourites -->
{% if get_favourite %}
<div class="col-md-8 col-md-offset-3 user_questions">
<h2 class="line">Favourites</h2>
{% for fav in get_favourite %}
<p>{{ fav.title }}</p>
{% endfor %}
</div>
{% endif %}
</div>
{% include 'accounts/information_form.html' %}
</div>
{% include 'base_footer.html' %}
{% endif %}
{% endblock %}

self.request.user refers to the currently logged in user. That is why you are getting the same result for all users.
To get what you want, you need to make the following change in your views:
user_prof = UserProfile.objects.get(pk=self.kwargs['pk'])
But also, I'm not sure why you are using an UpdateView when you simply want to display objects? You should use TemplateView instead.

Related

There was a problem with the button not working

I am a student who wants to be good at Django. The button does not work. If you press the button in detail.html, I want to save the product in DB as if I purchased it. My goal is to get the buyer, date, and product code as written on views.py. However, even if you press the button now, you can't save it in DB. What's the problem?
model.py
class Join(models.Model):
join_code = models.AutoField(primary_key=True)
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
part_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.join_code)
class Meta:
ordering = ['join_code']
Join/views
from datetime import timezone
from django.shortcuts import render
from zeronine.models import *
def join_detail(request):
product = Product.objects.all()
if request.method == "POST":
join = Join()
join.product_code = product
join.username = request.user
join.part_date = timezone.now()
join.save()
return render(request, 'zeronine/detail.html', {'product': product})
detail.html
{% extends 'base.html' %}
{% block title %} 상품 상세보기 {% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-4">
<img src="{{product.image.url}}" width="190%" style="margin-top: 35px;">
</div>
<div class="text-center col" style="margin-top:150px; margin-left:200px;">
<b><h4 class="content" style="margin-bottom: -5px;"><b>{{product.name}}</b></h4></b>
<br>
<div>
<!-- <span>주최자 : <b>{{ product.username }}</b></span><br>-->
<span style="color: #111111">모집기간 : <b>{{ product.start_date }} ~ {{ product.due_date }}</b></span>
</div>
<hr style="margin-top: 30px; margin-bottom: 30px;">
<p><span class="badge badge-dark">가격</span>
{% load humanize %}
{% for designated in designated_object %}
{% if designated.product_code.product_code == product.product_code %}
{{designated.price | floatformat:'0' | intcomma }}원
{% endif %}
{% endfor %}</p>
<span class="badge badge-dark">목표금액</span> {{ product.target_price | floatformat:'0' | intcomma }}원 <br><br>
<p class="badge badge-dark">공동구매 취지
{{product.benefit|linebreaks}}</p>
<p class="badge badge-dark">상세설명
{{product.detail|linebreaks}}</p>
<br>
<form action="" method="post">
{% csrf_token %}
<a onclick="alert('{{ product.name }} 공동구매 참여가 완료되었습니다.');" style="cursor:pointer;">
<form method="POST" action ="{% url 'zeronine:join_detail' %}">
{% csrf_token %}
<div class="form-group">
<button type="submit" action="{% url 'zeronine:join_detail' %}" class="btn btn-primary" style="float: right; background: #637B46; border: white">업로드</button>
</div>
</form>
</a>
</form>
</div>
</div>
</div>
{% endblock %}
I am not sure but you have a form inside a form in your template. maybe that is causing the problem.
also
in the POST section. it is best practice to use
join = Join.objects.create(product_code=product, ....)```

Django template tags conditionals

Right, am struggling with my blog app when trying to render some logic through the template view. So the idea is to render a one time only button for the newly authenticated users that do not have a post published and after the user has published its first post the button will be rendered within a for loop so he/she'll be able to create/delete a new one from there.
views.py
#login_required(login_url='app_users:login')
#allowed_users(allowed_roles=['admin', 'staff', 'users'])
def blog(request):
posts = BlogPost.objects.all().order_by('date_posted')
context = {'title': 'Blog', 'posts': posts}
return render(request, 'app_blog/blog.html', context)
models.py
class BlogPost(models.Model):
title = models.CharField(max_length=100, null=True)
content = models.TextField(null=True)
date_posted = models.DateTimeField(default=timezone.now, null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
blog.html
{% block content %}
{% if request.user not in posts|last %}
<div class="container" style="float: left;">
<a class="btn btn-primary btn-sm mt-1 mb-1" href="{% url 'app_blog:blog_create' user.id %}"><h5>C'mon {{ request.user.username }}, don't be shy! Create Your First Blog Post!</h5></a>
</div>
{% endif %}
<br>
<br>
{% for post in posts %}
<br>
<div class="container">
<article class="media content-section">
<img class="rounded-circle account-img" src="{{ post.author.profile.image.url }}" alt="Image could not be uploaded!">
<div class="card-body media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'app_blog:blog_user_detail' post.id %}">{{ post.author }}</a>
<small class="text-muted">{{ post.date_posted|date:"d F Y" }}</small>
</div>
<div class="article-metadata">
{% if post.author == request.user %}
<div>
<a class="btn btn-primary btn-sm mt-1 mb-1" href="{% url 'app_blog:blog_create' post.id %}">Create New Post</a>
<a class="btn btn-primary btn-danger btn-sm mt-1 mb-1" href="{% url 'app_blog:blog_delete' post.id %}">Delete</a>
</div>
{% endif %}
</div>
<h2><a class="article-title" href="{% url 'app_blog:blog_detail' post.id %}">{{ post.title }}</a></h2>
<p class="article-content">{{ post.content|safe }}</p>
</div>
</article>
</div>
<br>
{% endfor %}
{% endblock %}
So, again, end question would be about what sort of conditionals to use here:
{% if request.user not in posts|last %}
Thanks.
Not quite sure I fully understand but I will suggest something. A user who was a saved post should not see that button? If so, maybe something like this would work:
{% if request.user not in posts.authors.all %}
EDIT original solution won't work. posts is a queryset object
views.py
#login_required(login_url='app_users:login')
#allowed_users(allowed_roles=['admin', 'staff', 'users'])
def blog(request):
posts = BlogPost.objects.all().order_by('date_posted')
new_user = len(posts.filter(author=request.user)) == 0
context = {'title': 'Blog', 'posts': posts, 'new_user': new_user}
return render(request, 'app_blog/blog.html', context)
blog.html (just the condition)
{% if new_user %}

How to create a search function on a class-based list view?

I am trying to create a search function based on the title of my posts. Right now I am trying to implement this search using a filter but the list view is not rendering. I am unsure if I should implement a URL for my search function.
This is my model:
class Post(models.Model):
title = models.CharField(max_length=100)
image = models.ImageField(default = 'default0.jpg', upload_to='course_image/')
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=6)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
feedback = models.ManyToManyField(Feedback)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk' : self.pk})
This is my class-based list view:
class PostListView(ListView):
model = Post
template_name = 'store/sub_home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
ordering = ['date_posted']
paginate_by = 12
def get_queryset(self):
object_list = super(PostListView, self).get_queryset()
search = self.request.GET.get('q', None)
if search:
object_list = object_list.filter(title__icontains = title)
return object_list
This is my search bar:
<div id="search">
<form method='GET' action=''>
<input type="text" name='q' placeholder="">
<button id='search_holder'>
<img src="/static/store/search_icon.gif" id="search_icon">
</button>
</form>
</div>
This is my html that is rendering the posts:
{% extends "store/base.html" %}
{% block content %}
{% include "store/home_ext.html" %}
<div style="padding-top: 20px;" id="main" >
<section class="text-center mb-4">
<div class="row" id="random">
{% for post in posts %}
{% include "store/card.html" %}
{% endfor %}
</div>
<div class="row" id="subscription" style="display: none;">
{% if not subs %}
<h2>You have not subscribed to any course :/</h2>
{% endif %}
{% for post in subs %}
{% include "store/card.html" %}
{% endfor %}
</div>
<div class="row" id="content" style="display: none;">
{% if not mine %}
<h2>You have not published anything :/</h2>
{% endif %}
{% for post in mine %}
{% include "store/card.html" %}
{% endfor %}
</div>
</section>
{% include "store/pagination.html" %}
</div>
{% endblock content %}
This is my card.html:
{% load extra_filter %}
<div class="col-lg-3 col-md-6 mb-4">
<div id="course_card">
<div class="view overlay">
<img style="margin-left: -10px;" src="{{ post.image.url }}" alt="">
</div>
<div>
<div>
<strong>
{% if user.is_authenticated %}
<a class="title" href="{% url 'post-detail' post.id %}" >
{% else %}
<a class="title" href="{% url 'login' %}" >
{% endif %}
{% if post.title|length < 30 %}
<span>{{ post.title }}</span>
{% else %}
<span>{{ post.title|cut:27 }}</span>
{% endif %}
<span style="background-color: rgb(253, 98, 98);" class="badge badge-pill danger-color">NEW
</span>
</a>
</strong>
</div>
<div class="star-ratings-css">
<div class="star-ratings-css-top" style="width: {{ post.feedback|calc_rating }}%"><span>★</span><span>★</span><span>★</span><span>★</span><span>★</span></div>
<div class="star-ratings-css-bottom"><span>★</span><span>★</span><span>★</span><span>★</span><span>★</span></div>
</div>
<a href="{% url 'user-posts' post.author.username %}" class="author">
by {{ post.author }}
</a>
<div>
<strong style="text-align: right;" class="price">S${{ post.price }}
</strong>
</div>
<small class="date">
{{ post.date_posted|date:'d F y'}}
</small>
</div>
</div>
</div>
As Nalin Dobhal mentioned in comments, context_object_name should be posts not post. Because in template, you are iterating through posts context variable. Also, when using search functionality, the implementation should be like this:
class PostListView(ListView):
model = Post
template_name = 'store/sub_home.html' # /_.html
context_object_name = 'posts'
ordering = ['date_posted']
paginate_by = 12
def get_queryset(self, *args, **kwargs):
object_list = super(PostListView, self).get_queryset(*args, **kwargs)
search = self.request.GET.get('q', None)
if search:
object_list = object_list.filter(title__icontains = search)
return object_list
Because you are sending the search query through URL querystring(ie: url will look like /posts/?q=title in browser). I am using request.GET.get('q') to fetch those query string values, and use it to filter the queryset.

Want to print all groups to which user belongs

**Models.py**
class User(auth.models.User,auth.models.PermissionsMixin):
def __str__(self):
return "#{}".format(self.username)
def get_absolute_url(self):
return reverse("accounts:login")
class Group(models.Model):
name = models.CharField(max_length = 255,unique = True)
slug = models.SlugField(allow_unicode = True,unique = True)
description = models.TextField(default = '')
members = models.ManyToManyField(User,related_name = "group")
def save(self,*args,**kwargs):
self.slug = slugify(self.name)
super(Group,self).save(*args,**kwargs)
def get_absolute_url(self):
return reverse('groups:single',kwargs = {'slug':self.slug})
def __str__(self):
return self.name
**Views.py**
class ListGroups(ListView):
model = Group
**Html code**
<div class="col-md-8">
<div class="list-group">
{% if user.is_authenticated %}
<h2>Your Groups!</h2>
{% if user.group.count == 0 %}
<p>You have not joined any groups yet! <p>
{% else %}
{% for group in user.group.all %}
<a class="list-group-item" href="{% url 'groups:single' slug=group.slug %}">
<h3 class="list-group-item-heading">{{group.name}}</h3>
<div class="list-group-item-text container-fluid">
{{group.description|safe}}
<div class="row">
<div class="col-md-4">
<span class='badge'>{{group.members.count}}</span>
member{{group.members.count|pluralize}}
</div>
<div class="col-md-4">
<span class='badge'>{{group.posts.count}}</span>
post{{group.posts.count|pluralize}}
</div>
</div>
</div>
</a>
{% endfor %}
{% endif %}
{% endif %}
</div>
According to me it should print all the groups and it's details to which current logined user belongs but it is not printing anything.I have no idea what is wrong in this code.I have tried some other approaches but nothing works.Can anyone help?
Thanks in advance.
Well there is no variable named user in the template, hence all what you wrote will probably not work.
We can however obtain a list of Groups where the logged in user is member of, by first of all modifying the ListsGroup a bit:
from django.contrib.auth.mixins import LoginRequiredMixin
class ListGroups(LoginRequiredMixin, ListView):
model = Group
def get_queryset(self):
return Group.objects.filter(members=self.request.user)
Now we can render this like:
<div class="col-md-8">
<div class="list-group">
<h2>Your Groups!</h2>
{% for group in object_list %}
<a class="list-group-item" href="{% url 'groups:single' slug=group.slug %}">
<h3 class="list-group-item-heading">{{group.name}}</h3>
<div class="list-group-item-text container-fluid">
{{group.description|safe}}
<div class="row">
<div class="col-md-4">
<span class='badge'>{{group.members.count}}</span>
member{{group.members.count|pluralize}}
</div>
<div class="col-md-4">
<span class='badge'>{{group.posts.count}}</span>
post{{group.posts.count|pluralize}}
</div>
</div>
</div>
</a>
{% empty %}
<p>You have not joined any groups yet! <p>
{% endfor %}
</div>

Django in template timeuntil if statement

i would like to have kind of a todo list, where i have a model called "projekt" and i want colorize the html output depending on the timeuntil tag (if less then 7 days it should have the bootstrap class "danger" and if its more then 7 days it should have the class "success"
here my models.py:
class Project(models.Model):
name = models.CharField(max_length=100)
active = models.BooleanField(default=True)
beginning_project = models.DateField()
beginning_project_time = models.TimeField(blank=True, null=True)
deadline = models.DateField()
deadline_time = models.TimeField(blank=True, null=True)
beschreibung = models.TextField()
def __str__(self):
return self.nam
here's my views.py:
def Home(request):
proj = Project.objects.filter(active=True)
context = {
'proj':proj
}
return render(request, "home.html", context)
and as last my template:
home.html:
{% for proj in proj %}
<div class="row mx-auto text-center">
<div class="col-12 projcard">
<a href="{% url 'apps:Project' %}">
<p class="display-4 mx-auto">
{{ proj.name }}x
</p>
{% if proj.beginning_project|timeuntil > 7 %}
<button class="btn btn-success">
<u>
starts in {{ proj.beginning_project|timeuntil }}
</u>
</button>
{% else %}
<button class="btn btn-danger">
<u>
starts in {{ proj.beginning_project|timeuntil }}
</u>
</button>
{% endif %}
</a>
</div>
</div>
{% endfor %}
in your views.py you can do:
from datetime import datetime
def Home(request):
proj = Project.objects.filter(active=True)
today = int(datetime.now().strftime("%d"))
for p in proj:
if p.beginning_project.day - today > 7:
p.danger_mode = False
else:
p.danger_mode = True
and then in your home.html:
{% for proj in proj %}
<div class="row mx-auto text-center">
<div class="col-12 projcard">
<a href="{% url 'apps:Project' %}">
<p class="display-4 mx-auto">
{{ proj.name }}x
</p>
<button class="btn btn-{% if proj.danger_mode %}danger{% else %}success{% endif %}">
<u>
starts in {{ proj.beginning_project }}
</u>
</button>
</a>
</div>
</div>
{% endfor %}