TemplateSyntaxError: Variable 'user.profile.photo' is an invalid source - python-3.x

I have problem with accessing by the link. I am using easy-thumbnail framework, and I created simple view for user list to list all existing users.
Error message:
django.template.exceptions.TemplateSyntaxError: Variable
'user.profile.photo' is an invalid source.
Django Traceback throws me to this view.
views.py file:
#login_required
def user_list(request):
users = User.objects.filter(is_active=True)
return render(request,
'account/user/list.html',
{'section': 'people',
'users': users})
urls.py file:
path('users/', views.user_list, name='user_list'),
template list.html:
{% extends "base.html" %}
{% load thumbnail %}
{% block title %}People{% endblock %}
{% block content %}
<h1>People</h1>
<div id="people-list">
{% for user in users %}
<div class="user">
<a href="{{ user.get_absolute_url }}">
<img src="{% thumbnail user.profile.photo 180x180 %}">
</a>
<div class="info">
<a href="{{ user.get_absolute_url }}" class="title">
{{ user.get_full_name }}
</a>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
sample code from base.html:
<li {% if section == "people" %}class="selected"{% endif %}>
People
</li>
models.py:
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
date_of_birth = models.DateField(blank=True, null=True)
photo = models.ImageField(upload_to='users/%Y/%m/%d/',
blank=True)
def __str__(self):
return f'Profile for user {self.user.username}'
Thank you for the helping in advance.

Reviewed the documentation https://easy-thumbnails.readthedocs.io/en/latest/usage/#templates. Creates a thumbnail from an object (usually a file field). I tried it and it helped solve my problem:
<img src="{{ user.profile.photo.url }}">

I had this problem too. You can solve the problem with the following solution:
Instead of users = User.objects.filter(is_active=True), use profiles = Profile.objects.all()
Change as follows: return render(request,'account/user/list.html',{'section': 'people', 'profiles': profiles}).
In the list.html file, change as follows:
{% extends 'base.html' %}
{% load thumbnail %}
{% block title %}People{% endblock %}
{% block content %}
<h1>People</h1>
<div id="people-list">
{% for profile in profiles %}
<div class="user">
<a href="{{ profile.user.get_absolute_url }}">
<img src="{% thumbnail profile.photo 180x180 %}" alt="{{ profile.user.last_name }}">
</a>
<div class="info">
<a href="{{ profile.user.get_absolute_url }}" class="title">
{{ profile.user.get_full_name }}
</a>
</div>
</div>
{% endfor %}
</div>
{% endblock %}

Related

Can't show specific model field in my HTML template

On my main page i want to show a category just like {{ post.body }} but instead {{ post.body }} would be {{ post.category }} here.
{% extends "base.html" %}
{% block title %}Articles{% endblock title %}
{% block content %}
{% for post in post_list %}
<div class="card">
<div class="card-header">
<span class="font-weight-bold">{{ post.title }} |
</span> ·
<span class="text-muted">by {{ post.author }} |
{{ post.created_at }}</span>
</div>
<div class="card-body">
<!-- Changes start here! -->
<p>{{ post.body }}</p>
<p>{{ post.category }}</p>
Edit |
Delete |
Category
</div>
<div class="card-footer">
{% for comment in post.comment_set.all %}
<p>
<span class="font-weight-bold">
{{ comment.author }} ·
</span>
{{ comment }}
</p>
{% endfor %}
</div>
<!-- Changes end here! -->
</div>
<br />
{% endfor %}
{% endblock content %}
but cannot to figure out how. But cannot figure out how.
Here is my models
from django.conf import settings
from django.db import models
from django.urls import reverse
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return (self.name)
def get_absolute_url(self):
return reverse("home")
class Post(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
category = models.ManyToManyField(Category, related_name='categories')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("post_detail", kwargs={"pk": self.pk})
class Comment(models.Model):
article = models.ForeignKey(Post, null=True, blank=True, on_delete=models.CASCADE)
comment = models.CharField(max_length=140)
author = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,)
def __str__(self):
return self.comment
def get_absolute_url(self):
return reverse("post_list")
Thanks in advance
Added {{ post.category }} in here
{% extends "base.html" %}
{% block title %}Articles{% endblock title %}
{% block content %}
{% for post in post_list %}
<div class="card">
<div class="card-header">
<span class="font-weight-bold">{{ post.title }} |
</span> ·
<span class="text-muted">by {{ post.author }} |
{{ post.created_at }}</span>
</div>
<div class="card-body">
<!-- Changes start here! -->
<p>{{ post.body }}</p>
<p>{{ post.category }}</p>
Edit |
Delete |
Category
</div>
<div class="card-footer">
{% for comment in post.comment_set.all %}
<p>
<span class="font-weight-bold">
{{ comment.author }} ·
</span>
{{ comment }}
</p>
{% endfor %}
</div>
<!-- Changes end here! -->
</div>
<br />
{% endfor %}
{% endblock content %}
expected to see a category instead got post.category.None
To show the category in the HTML just like a property, you can add a property method in the model class and use it HTML, like this:
class Post(models.Model):
...
#property
def categories(self):
return ', '.join([x.name for x in self.category.all()]
Then use it template like:
{{ post.categories }}
Alternatively as it is a ManyToMany field, you can iterate through it in the template and render the categories:
{{ for c in post.category }} {{ c.name }} {% if not forloop.last %}, {% endif %} {{ endfor }}
Explanation of property method: property method allows you to convert a function to an attribute of the object of that class. self in the property method refers to itself (or the object itself). using self.category.all(), you are accessing the manytomany relation between Post and Category class. I am running a loop and access each of the Category objects connected to the Post object (the main object which are using in the template/html) and I am joining the names of the Category objects' names to form a comma separated string.

Uneven gallery with a repeated loop

I need to make an uneven gallery, where the user can upload an infinite number of images. The gallery is composed of a pattern of 7 images that is repeated indefinitely.
The website mainly uses Paragraphs, so I created a Paragraph Gallery, where the user can directly upload the media. I set up three image styles: small, tall, and big.
I also prepared a simple CodePen with the style solution. But now I’m struggling with the Twig template. I tried some solutions from previous discussions, but they either failed or didn’t generate the images.
{% block content %}
{% for image in content.field_images['#items'] %}
{% if image %}
<div class="gallery">
<div class="gallery-left">
<div class="inner-wrapper">
<div class="inner-left">
{% if loop.first %}
<div class="field__item">
<img src="{{ image|file_uri|image_style('tall') }}" alt="{{ image.alt }}">
</div>
{% endif %}
{% if loop.index == 2 %}
<div class="field__item">
<img src="{{ image|file_uri|image_style('small') }}" alt="{{ image.alt }}">
</div>
{% endif %}
</div>
<div class="inner-right">
{% if loop.index == 3 %}
<div class="field__item">
<img src="{{ image|file_uri|image_style('tall') }}" alt="{{ image.alt }}">
</div>
{% endif %}
{% if loop.index == 4 %}
<div class="field__item">
<img src="{{ image|file_uri|image_style('small') }}" alt="{{ image.alt }}">
</div>
{% endif %}
</div>
</div>
</div>
<div class="gallery-right">
{% if loop.index == 5 %}
<div class="field__item">
<img src="{{ image|file_uri|image_style('small') }}" alt="{{ image.alt }}">
</div>
{% endif %}
{% if loop.index == 6 %}
<div class="field__item">
<img src="{{ image|file_uri|image_style('tall') }}" alt="{{ image.alt }}">
</div>
{% endif %}
</div>
<div class="bottom">
{% if loop.index % 7 == 0 or loop.last %}
<div class="field__item">
<img src="{{ image|file_uri|image_style('big') }}" alt="{{ image.alt }}">
</div>
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
{% endblock %}
Based on #WPhil's idea with batch I would do it like it is proposed below.
Things to note:
Image uri can be retrieved from file entity and not from media nor field reference list item this is why content.field_images['#items'].0 is not enaugh and it should be something like content.field_images['#items'].0.entity.field_media_image.entity
batch filter has three arguments and within loops like this is important to reset the index so this is why the third arggument is FALSE
Gallery paragraph file
{% import "_impression_image.html.twig" as impression %}
{% block content %}
{% for impressions_gallery_batch in content.field_images['#items']|batch(7, NULL, FALSE) %}
{# Define all image file entities for given batch of image items #}
{% set image_entities = {} %}
{% for impressions_gallery_batch_item in impressions_gallery_batch %}
{% set image_entities = image_entities|merge([
impressions_gallery_batch["#{loop.index0}"].entity.field_media_image.entity,
]) %}
{% endfor %}
<div class="impressions-gallery">
<div class="impressions-left">
<div class="inner-wrapper">
{% if image_entities.0 %}
<div class="inner-left">
{{ impression.image(image_entities.0, 'impressions_small') }}
{{ impression.image(image_entities.1, 'impressions_tall') }}
</div>
{% endif %}
{% if image_entities.2 %}
<div class="inner-right">
{{ impression.image(image_entities.2, 'impressions_small') }}
{{ impression.image(image_entities.3, 'impressions_tall') }}
</div>
{% endif %}
</div>
</div>
{% if image_entities.4 %}
<div class="impressions-right">
{{ impression.image(image_entities.4, 'impressions_tall') }}
{{ impression.image(image_entities.5, 'impressions_small') }}
</div>
{% endif %}
{% if image_entities.6 %}
<div class="impressions-bottom">
{{ impression.image(image_entities.6, 'impressions_big') }}
</div>
{% endif %}
</div>
{% endfor %}
{% endblock %}
Image item macro function (_impression_image.html.twig)
{% macro image(image_entity_item, image_style) %}
{% if image_entity_item %}
<div class="field__item">
<img src="{{ image_entity_item.uri.value|image_style(image_style) }}" alt="{{ image_entity_item.alt }}">
</div>
{% endif %}
{% endmacro %}
Try something along the lines of the below, I have used the batch and splice filters to break up the image array into blocks and then conditional checks to determine the appropriate image size.
{% block content %}
{% for gallery_block in content.field_images['#items']|batch(7) %}
<div class="gallery">
<div class="gallery-left">
<div class="inner-wrapper">
<div class="inner-left">
{% for image in gallery_block|slice(0,3) %}
{% if image %}
<div class="field__item">
{% set size = ( loop.index is even ) ? 'small' : 'tall' %}
<img src="{{ image|file_uri|image_style(size) }}" alt="{{ image.alt }}">
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
<div class="gallery-right">
{% for image in gallery_block|slice(4,5) %}
{% if image %}
<div class="field__item">
{% set size = image.first ? 'small' : 'tall' %}
<img src="{{ image|file_uri|image_style(size) }}" alt="{{ image.alt }}">
</div>
{% endif %}
{% endfor %}
<div>
{% set bottom_image = gallery_block|last %}
{% if bottom_image %}
<div class="bottom">
<div class="field__item">
<img src="{{ bottom_image|file_uri|image_style('big') }}" alt="{{ bottom_image.alt }}">
</div>
</div>
{% endif %}
</div>
{% endfor %}
{% endblock %}

Django request.Get.get('page') returning none

Trying to use a paginator in a view. Getting none from page = request.GET.get('page'). As is, the call to paginator limits posts on a page properly, but any call to page sequence henceforth fails. Pages will display, but there will be nothing form pagination.html displayed. For clarity, Base.html is the base template from which all others inherit. list.html is the page where I expect to see pagination.html displayed.
This code is based off of the django manual. Is there something else that needs to be setup to give the requests querydict a key of 'page' or a better way to paginate?
views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def post_list(request):
object_list = Post.published.all() #a list of the posts
paginator = Paginator(object_list, 4) # 4 posts in each page
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# If page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request,'blog/post/list.html',{'page': page,'posts': posts})
pagination.html
<div class="pagination">
<span class="step-links">
{% if page.has_previous %}
Previous
{% endif %}
<span class="current">
Page {{ page.number }} of {{ page.paginator.num_pages }}.
</span>
{% if page.has_next %}
Next
{% endif %}
</span>
</div>
base.html
#...
<div id="content">
{% block content %}
{% include "pagination.html" with page=posts %}
{% endblock %}
</div>
#...
list.html
{% extends "blog/base.html" %}
{% block title %}My Blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{% endblock %}
When you fill a block in a child template it replaces the super template's block's content (not literally the block named content here). If you want to keep the parent's block along with some extra content, you should use {{ block.super }}, i.e. list.html should be:
{% extends "blog/base.html" %}
{% block title %}My Blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{{ block.super }}
{% endblock %}

Big Cartel Luna Theme. Cart will not proceed to checkout

I'd love some help with this.
On the Cart page, when the "use my stores Layout" is selected, when customers click "Check Out", it just keeps cycling on the page and won't proceed to checkout. This is a known issue with the Luna theme for Bigcartel.
The solution I found says you need to uncheck it, but when you do, you get the error message:
"You must include {{ head_content }} inside the <head> tag of your content"
This means there's no page formatting in the code. I'm not big on the code, though I've tried for a bit to get this to work, stealing code for other pages in the theme, and failed. (it's been years since I've messed with code, so any help would be a big one).
Thank you
Here's the code for the page:
<header class="product_header page_header">
<h1>Cart</h1>
<span class="dash"></span>
</header>
{% if cart.items != blank %}
<form id="cart-form" {% unless cart.shipping.enabled or cart.discount.enabled %}class="no_options"{% endunless %} method="post" action="/cart" accept-charset="utf8">
<input type="hidden" name="utf8" value='✓'>
<div id="cart_description">
<section id="cart_items">
<ul>
{% for item in cart.items %}
<li class="cart_item {% unless item.product.has_default_option %}with_option{% endunless %}" id="item-{{ item.id }}">
<div class="item_image"><img src="{{ item.product.image | product_image_url: "thumb" }}" alt="Photo of {{ item.name }}"></div>
<dl>
<dt>{{ item.product.name }}</dt>
<dd class="item_price">{{ item.unit_price | money_with_sign }}{% if item.quantity > 1 %}<span class="item_quantity">(x{{ item.quantity }})</span>{% endif %}</dd>
<dd class="quantity_input">{{ item | item_quantity_input }}</dd>
{% unless item.product.has_default_option %}<dd class="item_option">{{ item.option.name }}</dd>{% endunless %}
</dl>
Remove item
</li>
{% endfor %}
</ul>
</section>
{% if cart.shipping.enabled or cart.discount.enabled %}
<section id="cart_options">
<ul>
{% if cart.shipping.enabled %}
{% if cart.shipping.strict %}
<li id="shipping_option">
<label for="country">Shipping</label>
{{ store.country | country_select }}
{% if cart.shipping.pending %}
{% if cart.country %}
<span class="no_shipping">We don't ship to {{ cart.country.name }}</span>
{% endif %}
{% endif %}
</li>
{% endif %}
{% endif %}
{% if cart.discount.enabled %}
<li id="cart_discount" class="cart_item">
{% if cart.discount.pending %}
<label id="cart_discount_label" for="cart_discount_code">Discount</label>
{{ cart.discount | discount_code_input }}
{% elsif cart.discount.free_shipping %}
<label for="cart_discount_code">Discount</label>
<p>{{ cart.discount.name }}</p>
{% else %}
<label for="cart_discount_code">Discount</label>
<p>{{ cart.discount.name }}</p>
{% endif %}
</li>
{% endif %}
</ul>
<div class="cart-update">
<button id="update-btn-footer" class="update-btn button disabled" name="update" type="submit" title="Update your cart total"><span>Update total</span></button>
</div>
</section>
{% else %}
<section id="cart_options" class="solo_update">
<div class="cart-update">
<button id="update-btn-footer" class="update-btn button disabled" name="update" type="submit" title="Update your cart total"><span>Update total</span></button>
</div>
</section>
{% endif %}
</div>
<section id="cart_summary">
<ul>
<li>
<h3>Items</h3>
<span>{{ cart.subtotal | money_with_sign }}</span>
</li>
{% if cart.shipping.enabled %}
<li id="cart-shipping-tax">
<h3>Shipping</h3>
{% if cart.shipping.pending %}
{% if cart.country %}
<span class="shipping-amount">Select another country</span>
{% else %}
<span class="shipping-amount">Select country</span>
{% endif %}
{% else %}
<span class="shipping-amount">{{ cart.shipping.amount | money_with_sign }}</span>
{% endif %}
</li>
{% else %}
<li id="cart-shipping-tax" class="not_set">
<h3>Shipping</h3>
<span>Applicable fees apply</span>
</li>
{% endif %}
{% if cart.discount.enabled %}
{% if cart.discount.pending %}
{% elsif cart.discount.free_shipping %}
<li>
<h3>Discount</h3>
<span>Free shipping!</span>
</li>
{% else %}
<li>
<h3>Discount</h3>
<span>-{{ cart.discount.amount | money_with_sign }}</span>
</li>
{% endif %}
{% endif %}
<li id="cart_total">
<h3>Total</h3>
<h2>{{ cart.total | money_with_sign }}</h2>
</li>
</ul>
<button id="checkout-btn" class="button" type="submit" title="Checkout">Checkout</button>
</section>
</form>
{% else %}
<div id="cart_empty">
<p>Your cart is empty! Sounds like a good time to start shopping.</p>
</div>
{% endif %}
Thanks!
There's not any known issues with the Luna theme code that prevents customers from being able to check out - you shouldn't need to edit any settings or change any code.
It sounds like your custom domain might be setup incorrectly with an IFRAME though, as this is known to cause problems with the cart page redirecting to the checkout. You can test this by using your storename.bigcartel.com URL vs. the custom domain to see if this is the case.
Since this isn't related specifically to your theme, you'll want to get in touch with Big Cartel support directly and they should be able to help troubleshoot further.

How to change which is the active menu without js in Twig?

I'm using Twitter Bootstrap and Symfony 2 with Twig. I have this for all my pages:
<div class="navbar navbar-inverse navbar-static-top">
<div class="navbar-inner">
<a class="brand" href="{{ path('home') }}">BudgetTracker</a>
<ul class="nav">
<li class="active">Expenses</li>
<li>Reports</li>
<li>Categories</li>
<li>Months</li>
<li>Bank Accounts</li>
</ul>
</div>
</div>
I don't want to copy it on each page... The problem is that the class active attribute should be put only for the cuurent page. Is there a way to succeed without using JavaScript, only with some king of macro or include? Thank you very much in advance!
UPDATE
<div class="navbar navbar-inverse navbar-static-top">
<div class="navbar-inner">
<a class="brand" href="{{ path('home') }}">BudgetTracker</a>
<ul class="nav">
{% if var == 'Expenses' %}
<li class="active">Expenses</li>
{% else %}
<li>Expenses</li>
{% endif %}
{% if var == 'Reports' %}
<li class="active">Reports</li>
{% else %}
<li>Reports</li>
{% endif %}
{% if var == 'Categories' %}
<li class="active">Categories</li>
{% else %}
<li>Categories</li>
{% endif %}
{% if var == 'Months' %}
<li class="active">Months</li>
{% else %}
<li>Months</li>
{% endif %}
{% if var == 'Bank Accounts' %}
<li class="active"><li>Bank Accounts</li>
{% else %}
<li><li>Bank Accounts</li>
{% endif %}
</ul>
</div>
</div>
My not very elegant try. And I call it with:
{% include 'EMBudgetTrackerBundle::navbar.html.twig' with {'var':'Categories'} %}
The easy way to do this is using the routes:
<ul class="nav nav-pills">
<li {% if app.request.attributes.get('_route') == 'your_route' %} class="active" {% endif %}>
MyTitle
</li>
...
</ul>
This is an adaptation of a solution provided by #Winzou.
It is quite simple:
Define this as a single twig with
{% block menu_block %} //your content here {% endblock %}
Use your block in every page
{% block menu_block %} {{ parent() }} {% endblock %}
Make conditional statements for give your class at the current menu element. Obviously you have to pass to your twig (or retrieve from request, i.e.) the name or id of your page, to make what you're trying to do
Here's an example.
{% if menu.url == current_url %} class="active"{% endif %}

Resources