Django include template as variable to use in default - django

I'd like to include a default template as a variable to pass it into a default case, like below:
<div class="row max-h-200 overflow-hidden">
{% include 'blog/userprofile_deleted.html' as deleted_profile %}
{{ user.profile.bio | safe | default:deleted_profile }}
</div>
Is this possible in django 3.2.9 ?
Currently I have to write out the default text as html in a single line:
<div class="row max-h-200 overflow-hidden">
{{ user.profile.bio | safe | default:'<h4> Very long html string! </h4> <span>Comment as <b>you</b> with your own profile!</span><span>Create your Account at the bottom of the page,or by visiting <code>/register</code> !</span>' }}
</div>

Related

Concatenate string and UUID in Django Template

I am trying to concatenate the UUID of a record with a base URL to create a scannable QR code that will link to the direct record on the website. When trying to concatenate the two it fails and yields nothing.
The relevant part is device.id which is a UUID for the device. I've string |stringformat:"s" as well and that didn't work. I don't know what the best practice to do this is and am struggling.
<div class="row">
<div class="col-xs-12 text-center">
{% with "http://127.0.0.1:8000/ims/device/"|add:device.id as deviceurl %}
{% qr_from_text deviceurl size=25 %}
<p class="small text-center">{{deviceurl}}</p>
{% endwith %}
<p class="small text-center">{{ device.id }}</p>
</div>
</div>
Since the |add filter only works with two strings it cannot be used as a general answer. I created a custom |addstr filter and included it in the file which solved the problem.
How to concatenate strings in django templates?

set a variable in django template file, and update it after iteration

Trying to set variable in django template, and make a simple rule to update it after iteration. Here is my template:
{% for adv in advs %}
<div class="media-item big" style="top: 18%;left:{% cycle '304' '1078' %}px;">
<div class="media-item__tags">
{{ adv.year }}
{{ adv.payer}}
</div>
<div class="media-item__content">
<div class="media-item__background">
<div class="media-item__canvas">
<div class="media-item__canvas-background" style="background-image: url({{adv.image.url}})"></div>
</div>
<h2 class="topic white upcase fixed-size">{{ adv.name }}</h2>
Смотреть проект
</div>
</div>
</div>
In first div i need to make different 'left:' value. I want to make rule: after every iteration, value changes from base=304 to base+774 px. I tryed to do it somehow with {% cycle %} but it doesnt work for me, also tryed to set variables with {% with %} tag, but didnt find any information about how to update them.
You can set the style by multiplying the current counter from 0...n with 774 and add base value 304. For this, you'll need a custom template tag.
Create a templatetags directory in your app. Add an empty __init__.py and multiply_add.py.
multiply_add.py
from django import template
register = template.Library()
#register.simple_tag
def mul_add(a, b, base_value):
return (a * b) + base_value
template.html
{% load multiply_add %}
{% for adv in advs %}
<div class="media-item big" style="top: 18%;left:{% multiply_add forloop.counter0 774 304 %}px;">
<div class="media-item__tags">
{{ adv.year }}
{{ adv.payer}}
</div>
<div class="media-item__content">
<div class="media-item__background">
<div class="media-item__canvas">
<div class="media-item__canvas-background" style="background-image: url({{adv.image.url}})"></div>
</div>
<h2 class="topic white upcase fixed-size">{{ adv.name }}</h2>
Смотреть проект
</div>
</div>
</div>

Display part of the content data

I have the following template code:
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ article.title }}</h3>
</div>
<div class="panel-body">
{{ article.content }} <!--will display the full text-->
</div>
I intend to show the first 200 characters of the content, like:
{{ article.content|length=200 }}
How to achieve such a constrain on the text.
There are two template filters here that are useful: slice and truncatechars.
slice limits an iterable (here a string) to a given number, for example:
{{ variable | slice:":200" }}
whereas truncatechars does approximately the same, except that in case the string is longer than the upper bound (here 200), it will slice to the upperbound minus three, and add an ellise:
{{ variable | truncatechars:"200" }}
For a smaller upperbound, to demonstrate the difference, for a string variable = "foobarqux" we would get:
{{ variable | slice:":6" }} # foobar
{{ variable | truncatechars:"6" }} # foo...
The two thus differ: the latter gives a textual hint that there is actually more content. Of course it depends on the specific situation which filter suits your needs.
A nice thing is that you can emulate truncatechars in terms of slice:
{{ variable | truncatechars:":6" }}
is equivalent to:
{% if variable|length > 6 %}{{ variable|slice:":3" }}...{% else %}{{ variable }}{% endif %}
But it is of course not the most elegant solution: in case you want truncatechars behavior, it is better to use the specific filter.
You can use truncatechars filter:
{{ article.content|truncatechars:200 }}

Data base saving & Redirection issue using django

I have an issue, I do not know why it is happening and how to solve it;
My app ask a user to create a project and is redirect directly to the project detail page. On that detail page if a team_id is empty I ask the user to create a team and when the team is created the user is redirected again to the project detail page to now be able to populate his team.
I used the code {% if Project.team_id == None %} when the user is redirected after creating his team but it is not working .. could you please help ? It is like before the redirection the new team is not saved in the Db ..
my html:
{% extends 'base.html' %}
{% block body %}
<div class="container">
<div class="jumbotron">
<h2>Welcome to your Project {{ project.name }} Detail page</h2>
</div>
{% if Project.team_id == None %}
<div class="invite-team">
<div class="jumbotron">
<div class="jumbo-text">
<h3>It is time to link a team to your project now create a new team and add team members</h3>
</div>
<div class="jumbo-button">
<span class="glyphicon glyphicon-plus"></span> Create a new team
</div>
</div>
{% else %}
<div class="invite-teammembers">
<div class="jumbotron">
<div class="jumbo-text">
<h3>The team {{ project.team_id }} has beed created, we now need to add TeamMembers</h3>
</div>
<div class="jumbo-button">
<span class="glyphicon glyphicon-plus"></span> Create a new team
</div>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock%}
Looking at your surrounding code, you are using project as the container of your project. However, in your statement you are using Project (first character uppercase). Changing Project to project might help.
Your comment question:
what do you mean "Looking at your surrounding code, you are using project as the container of your project". my model Project is with a capital letter why now it is without ?
With looking at the surrounding code I mean that I literally looked at your code how you are using the variables in the other parts of your code. I am not sure if you are using CBV (class based views) or FBV (function based views).
With CBV the object is added to the context with the name defined in:
DetailView:81
or ListView:104
You can override the context object name by using the context_object_name in the View class
If you are using FBV, you have added it to the context manually as something like:
return render(request, 'myapp/template.html', {
'project': <project_query_or_variable>,
})

get_profile alternative in for loop django

I'm trying to get information of a users avatar based in an extended profile model. I usually call the information via get_profile(). However on this occasion the call is within a for loop in the template and I get errors if one of the users are the same.
How would I go about avoiding this error?
{% for fevent in fevents %}
<!-- EVENT ><! -->
<div class="event">
<div class="pic">
{{ fevent.getPublishedPredictionsCount }}
<img src="{% thumbnail fevent.artwork.get_absolute_url 100x98 crop,upscale %}" alt="" width="100" height="98" />
<div class="overlay">
</div>
</div>
<h1>{{ fevent.title|trunchar:30 }}</h1>
{% autoescape off %}
{{ fevent.getEventPredictionScore|makestars }}
{% endautoescape %}
<ul class="details">
<li class="cat">
Category: {{ fevent.catagory }}
</li>
<li class="location">
{{ fevent.location }}
</li>
<li class="date">
{{ fevent.date_and_time }}
</li>
<li class="time">
7:00pm - 8:00pm
</li>
</ul>
<!-- CLEAR ><! --><div class="clear"></div>
<div class="hype">
<div class="avatar">
<img src="{% thumbnail fevent.owner.get_profile.avatar.get_absolute_url 120x120 crop,upscale %}" alt="" width="120" height="120" />
</div>
<p>{{ fevent.description|trunchar:200 }}… Read More</p>
</div>
<!-- CLEAR ><! --><div class="clear"></div>
</div>
<!-- END OF EVENT ><! -->
{% endfor %}
The problem is here:
{% thumbnail fevent.owner.get_profile.avatar.get_absolute_url 120x120 crop,upscale %}
Error Message returned:
Caught MultipleObjectsReturned while rendering: get() returned more than one UserProfile -- it returned 2! Lookup parameters were {'user__id__exact': 4L}
To expand on what Matt said, while using get_or_create is a good idea, you should definitely define your profile model's User link with a OneToOneField, instead of a ForeignKey.
user = models.OneToOneField(User, verbose_name=_(u'user'))
Now, if you forget to use get_or_create(), or somehow accidentally try to create a duplicate profile for the same user, the database will raise an IntegrityError.
That error means there are two UserProfile objects in the database matching the query used by get_profile, not that get_profile was called twice. You need to remove one of those profile objects from the database and make sure there aren't multiples created again. You should be able to use the get_profile method multiple times without issue. Maybe you have a get_or_create call in that function without checking the proper values.