I am working on a website using Django, where users can send friend
request to another user and I came up with an error on my code. Queryset object has no attribute user. According to my attached images, when I click on the follow button of the first user, all buttons changes text to 'cancel', but when I click on the button of the second user it does not change the text. I want when button clicked button text should be able to change for each users.
def home(request):
p = Profile.objects.exclude(user=request.user)
u = p.user
sent_request = FriendRequest.objects.filter(from_user=p.user)
button_status = 'none'
if p not in request.user.profile.friends.all()
button_status = 'not_friend'
if len(FriendRequest.objects.filter(from_uset=request.user).filter(to_user=p.user)) == 1:
button_status='add_request'
if len(FriendRequest.objects.filter(from_user=p.user).filter(to_user=request.user)) == 1:
button_status='cancel_request'
context = {'u':u, 'p':p, 'sent_request',:sent_request, 'button_status':button_status,}
return render(request, 'home.html', context)
{% for profile in p %}
{{ profile }}
{% if not request.user in u %}
{% if button_status == 'not_friend' %}
href = add url here
{% elif button_staus == 'cancel_request' %}
href = cancel request url here
{% endif %}
{% endif %}
{% endfor %}
#This only execute once on template, instead of twice (duplicate). How do I make this display twice in template?
{% for data in profile_and_button_status %}
{% data.0.user.username %}
#All codes here
{% endfor %}
{% if forloop.counter == 1 %}
{% for data in profile_and_button_status %}
#All codes here
{% data.0.user.username %}
{% endfor %}
{% endif %}
Because .exclude() will give you an queryset. So, you have to first iterate that queryset and get required user from there.
Because queryset it mean the list.
I think you have to pass zip of profiles list p and button status list button_status of a particular users as below...
def home(request):
p = Profile.objects.exclude(user=request.user)
all_profile_users = []
button_status_list = []
for user_obj in p:
u = user_obj.user
all_profile_users.append(u)
sent_request = FriendRequest.objects.filter(from_user=u)
friends = Profile.objects.filter(user=request.user, friends__id=user_obj.id).exist()
button_status = 'none'
if not friends
button_status = 'not_friend'
if len(FriendRequest.objects.filter(from_uset=request.user).filter(to_user=p.user)) == 1:
button_status='add_request'
if len(FriendRequest.objects.filter(from_user=p.user).filter(to_user=request.user)) == 1:
button_status='accept_request'
button_status_list.append(button_status)
context = {'u':all_profile_users, 'profile_and_button_status': zip(p, button_status_list), 'sent_request':sent_request}
Then, iterate profile_and_button_status in template as below...
{% for data in profile_and_button_status %}
<div class="row mb-2">
... YOUR DESIGN CODE ...
{{ data.0.user.username }}
{% if not request.user in u %}
{% if data.1 == 'not_friend' %}
... YOUR DESIGN CODE ...
{% elif data.1 == 'follow_request_sent' %}
... YOUR DESIGN CODE ...
And so on for other conditions.
For remove friend :
def remove_friend(request, id):
... YOUR LOGIC ...
frequest = FriendRequest.objects.filter(from_user=from_user, to_user=request.user).first()
if frequest is None:
frequest = FriendRequest.objects.filter(from_user=request.user, to_user=from_user).first()
user1 = frequest.to_user
user2 = from_user
... YOUR LOGIC ...
Related
I want to declare a flag variable in django template and the change it if some thing happened.
But when I change value of variable by custom tag it is declared a new variable and doesn't change.
for example my template tag and django template is:
template tag:
#register.simple_tag
def update_variable(value):
return value
html:
{% with True as flag %}
<h1>1: {{ flag }}</h1>
{% for e in events %}
{% if e.title == '***' %}
{% update_variable False as flag %}
<h1>2: {{ flag }}</h1>
{% endif %}
{% endfor %}
<h1>3: {{ flag }}</h1>
{% endwith %}
and result is:
1: True
2: False
3: True
But the end result should be False! How to do this?
I find a solution for it. for check all element of list we can use custom filter an do some thing there:
html:
//load custom filter
{% load my_filters %}
{% if "anything we want"|is_in:events.all %}
//do some thing...
{% else %}
//do some thing...
{% end if%}
custom filter in my_filter file:
register = template.Library()
def is_in(case, list):
for element in list:
if element.time_span == case:
return True
return False
register.filter(is_in)
I am using Django to render a menu of items. I can get the content I want just fine, but when I return it to the django template, it's just a json string so it won't iterate correct. How do I tell django to return it as an iterable object?
I ran across this article. Maybe I want to merge query sets?
Python
def index(request):
if not request.user.is_authenticated:
return redirect('/login', {'message': None})
try:
menu_categories = MenuCategory.objects.all()
menu = []
for cat in menu_categories:
items = MenuCategoryItems.objects.filter(category_id=cat.id).all()
menu.append({'category': cat, 'items': items})
context = {'menu': menu}
# for cat in menu_categories:
# items = menu_items.filter(category_id=cat.id)
# category_items = []
# for item in items:
# category_items.append({
# "name": item.name,
# "price": float(item.price),
# "id": item.id
# })
# menu.append({"category": cat.name, "items": category_items})
except Exception:
print('failure')
return render(request, 'index.html', context)
Template
{% for category in menu %}
<div>{{ category.name }}</div>
{# {% for item in category.items %}#}
{# <div>{{ item.name }} | {{ item.price }}</div>#}
{# {% endfor %}#}
{% endfor %}
I think I have found my answer. This worked for me but I'm not sure if it's the 'preferred' way.
Python
def index(request):
if not request.user.is_authenticated:
return redirect('/login', {'message': None})
try:
menu_categories = MenuCategory.objects.all()
menu = []
for cat in menu_categories:
items = MenuCategoryItems.objects.filter(category_id=cat.id).all()
menu.append({'category': cat, 'items': items.values})
context = {'menu': menu}
except Exception:
print('failure')
return render(request, 'index.html', context)
Template
{% for category in menu %}
<div><strong>{{ category.category.name }}</strong></div>
{% for item in category.items %}
<div>{{ item.name }} - {{ item.price }}</div>
{% endfor %}
{% endfor %}
I am passing a generator object results from fx_rates view to template like this:
def fx_rates(request):
if request.method != 'POST':
form = FxForm()
results=[]
else:
form = FxForm(request.POST)
if form.is_valid():
scraper = FxScraper()
scraper.from_currencies.append(form.cleaned_data['from_currencies'])
scraper.dates = form.cleaned_data['dates'].split(" ")
scraper.to_currency = form.cleaned_data['to_currency']
results = scraper.results()
context = {'form':form, 'results':results}
return render(request, 'map_assistant/fx_rates.html',context)
In the template for this view I am using the below to display results:
<ul>
{% for result in results %}
<li>{{result}}</li>
{% endfor %}
</ul>
(guess I can change it to {{next(results)}} once the issue described below is solved).
The problem is I don't know how to prevent "[]" from displaying when the view is called using GET method (see if clause above).
I cannot delete results=[] line because I will get an error when the view is called using GET.
Guess I would need to somehow remove results from context dictionary when the method is GET?
When the method is GET, try:
results = ""
This way, results is given a value of empty.
You can do something like this
def fx_rates(request):
show_div = 'none'
if request.method != 'POST':
form = FxForm()
results=[]
else:
show_div = 'block'
form = FxForm(request.POST)
if form.is_valid():
scraper = FxScraper()
scraper.from_currencies.append(form.cleaned_data['from_currencies'])
scraper.dates = form.cleaned_data['dates'].split(" ")
scraper.to_currency = form.cleaned_data['to_currency']
results = scraper.results()
context = {'form':form, 'results':results, 'show_div':show_div}
return render(request, 'map_assistant/fx_rates.html',context)
and your html will look like this
<div style="display:{{show_div}}">
<ul>
{% for result in results %}
<li>{{result}}</li>
{% endfor %}
</ul>
</div>
or simply check
{% if result %}
<ul>
{% for result in results %}
<li>{{result}}</li>
{% endfor %}
</ul>
{% else %}
{% endif %}
In theory i did what i'm supposed to do in order to store some data in session variables but my controllers can't reach them. Here's the code:
#expose('')
#require(predicates.not_anonymous())
def savecustomer(self, customer=None, **kw):
if customer is None:
flash(_('Select a customer!'), 'error')
redirect('/')
customer = DBSession.query(Customer).filter_by(customer_id=customer).first()
session.delete()
session['customer'] = True
session['customer_id'] = customer.customer_id
session['customer_name'] = customer.customer_name
...
session.save()
and here is my view code:
{% if request.identity %}
{% if session['customer'] %}
<div class="customer"><i>{{ session['customer_name'] }}
{% if session['customer_type'] %} {{ session['customer_type'] }} {% endif %}
</i></div>
{% else %}
<div class="nocustomer">No customer selected</div>
{% endif %}
{% endif %}
and here's my "debugging":
for i in session.iterkeys():
print i
for i in session.itervalues():
print i
customer
customer_id
customer_name
True
3
Ciccio Pasticcio S.p.a.
and if i run the same code in another controller it gives me this:
_id
832f62d3bc5140c4a9f3ba36bc3e876a
What am i doing wrong? (this used to work until i "fixed" something else :) )
I solved the error by removing
session.delete()
I have a model that looks like this:
class ListEntry(models.Model):
STATUS_CHOICES = (
('PL', _('Playing')),
('CO', _('Completed')),
('OH', _('On-hold')),
('DR', _('Dropped')),
('WA', _('Want to play')),
)
user = models.ForeignKey(User)
game = models.ForeignKey(Game)
status = models.CharField(_('Status'), max_length=2,
choices=STATUS_CHOICES)
In my views I'm filtering the entries by user like this:
class GameListByUserView(ListView):
model = ListEntry
template_name = 'game_list_by_user.html'
def get_queryset(self):
self.user_profile = get_object_or_404(User, username=self.kwargs['slug'])
return ListEntry.objects.filter(user=self.user_profile)
def get_context_data(self, **kwargs):
context = super(GameListByUserView, self).get_context_data(**kwargs)
context['user_profile'] = self.user_profile
return context
What I'm trying to do now is split this query (ListEntry.objects.filter(user=self.user_profile)) into subgroups depending on the status attribute, so the rendered template looks like:
UserFoo's list
=========================
Playing
Game 1
Game 2
Game 3
Completed
Game 4
Game 5
Game 6
I know I can do something like:
q = ListEntry.objects.filter(user=self.user_profile)
games_dict = {}
games_dict['playing'] = q.filter(status='PL')
games_dict['completed'] = q.filter(status='CO')
And so on, and iterate over the keys in the template. Or (in the template):
{% for s in status_choices %}
{% for entry in object_list %}
{% if entry.status == s %}
Render things
{% endif %}
{% endfor %}
{% endfor %}
But isn't there a better, optimized way to do this without hitting the database every time I get a subquery by status, and without iterating over the objects list multiple times?
You are looking for the regroup filter
{% regroup object_list by status as games_list %}
<ul>
{% for game in games_list %}
<li>{{ game.grouper }}
<ul>
{% for item in game.list %}
<li>{{ item}}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
You might have to customize the way the elements render, but I will let you figure that out yourself.