I've been trying to generate URL's on a detailpage for my app. I want the url of the QR-Code to be a link to the detail page of the item. What i have right now is this:
<img src="{% qr_url_from_text "localhost:8000/items/{{item.id}}" %}" alt="QR-Code for the item">
the Problem with this is, that i want to give item.id as part of the url. But it's not seen as variable, so when i scan the qr-code, it opens the page http://localhost:8000/items/{{item.id}}, but i want it to have the actual id (e.g. 4) in the url, not {{item.id}} as string.
Is there any way to put variables in those URL names?
Thank you already
Do not make url using variable in template.
Do it in view, as context variable, and than use that variable in place of "localhost:8000/items/{{item.id}}" in template .
So, in your view, you will have something like:
def yourview(request, pk):
qrcode_url = "localhost:8000/items/" + str(pk)
context = {
qrcode_url: 'qrcode_url',
}
return render(request, 'yourtemplate.html', context)
and than in template:
<img src='{% qr_url_from_text qrcode_url size="t" version=10 image_format="png" error_correction="L" %}' alt="QR code">
Related
I have a Post model that requires a certain category before being added to the database, and I want the category to be generated automatically. Clicking the addPost button takes you to a different page and so the category will be determined by taking a part of the previous page URL.
Is there a way to get the previous page URL as a string?
I have added my AddPost button here.
<aside class="addPost">
<article>
<form action="/Forum/addPost">
<input type="submit" name="submit" value="Add Post"/>
</form>
</article>
</aside>
You can do that by using request.META['HTTP_REFERER'], but it will exist if only your tab previous page was from your website, else there will be no HTTP_REFERER in META dict. So be careful and make sure that you are using .get() notation instead.
# Returns None if user came from another website
request.META.get('HTTP_REFERER')
Note: I gave this answer when Django 1.10 was an actual release. I'm not working with Django anymore, so I can't tell if this applies to Django 2
You can get the referring URL by using request.META.HTTP_REFERER
More info here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
I can't answer #tryingtolearn comment, but for future people, you can use request.META['HTTP_REFERER']
Instead of adding it to your context, then passing it to the template, you can place it in your template directly with:
Return
A much more reliable method would be to explicitly pass the category in the URL of the Add Post button.
You can get the previous url in "views.py" as shown below:
# "views.py"
from django.shortcuts import render
def test(request):
pre_url = request.META.get('HTTP_REFERER') # Here
return render(request, 'test/index.html')
You can also get the previous url in Django Template as shown below:
# "index.html"
{{ request.META.HTTP_REFERER }}
I have a django template where i send an image actually its for an email.It only works when i keep the whole url like abc.com/images/a.png .
i have sent he image like this:
{
'picture':picture.url
}
This is the code for template that i am using for email template:
<img src="{{picture}}" alt="image" width="200" height="200" >
Am i missing something? as it only works when i keep the whole url?
To build an absolute URL you can use request.build_absolute_uri(picture.url) in your view.
Following is my code, Every time I click Like (or Dislike) link, both Dislike and Like are incremented.
I am new to django, your help will be much appreciated. Thank you
Here is my models.py,
from django.db import models
from django.urls import reverse
# Create your models here.
class Movies(models.Model):
Director=models.CharField(max_length=30)
Cast_I=models.CharField(max_length=30)
Cast_II=models.CharField(max_length=30)
Name=models.TextField()
ReleaseYear=models.IntegerField()
ImdbRating=models.CharField(max_length=2)
Genre=models.TextField(null=True)
Language=models.CharField(max_length=20,null=True)
Like=models.IntegerField()
Dislike=models.IntegerField()
def like_this_movie(self):
self.Like+=1
self.save()
return reverse ('list',kwargs={})
def dislike_this_movie(self):
self.Dislike+=1
self.save()
return reverse ('list',kwargs={})
Here is the template,
{% block content %}
<p>
Like
Dislike
</p>
{% endblock %}
Here is my view class,
class MovieDetailView(DetailView):
template_name='movie/detail.html'
queryset=Movies.objects.all()
The templates in Django don't work like that, everything you put inside {{ }} is rendered on the server and then the page is sent to the client, so it is not possible to run a function like that.
You would have to do something like an AJAX request to another page which runs like_this_movie and takes the Movies id as a parameter. To send to AJAX request you can use Javascript with jQuery.
The problem is that each time you load the page both values are incremented because you call both functions in each call. This link will help you on how do it => How to make user to Like/Dislike post only for once in Django?
I have resolved my bug by adding those like_this_movie and dislike_this_movie function to my views.py and updating my urls.py and template. Thank you guys for your valuable answer.
views.py,
def like_this_movie(request,key):
obj=Movies.objects.get(pk=key)
obj.Like+=1
obj.save()
return redirect('/movie/list')
def dislike_this_movie(request,key):
obj=Movies.objects.get(pk=key)
obj.Dislike+=1
obj.save()
return redirect('/movie/list')
urls.py,
urlpatterns=[
path('list/<int:key>/like',like_this_movie,name='like'),
path('list/<int:key>/dislike',dislike_this_movie,name='dislike')
]
template,
Like
Dislike
Now I have resolved this by using jQquery AJAX, like_this_movie and dislike_this_movie function returns json value to ajax request. Now page doesn't reload every time I hit like or dislike button. Thank you guys for your valuable answer.
views.py,
def like_this_movie(request,key):
obj=Movies.objects.get(pk=key)
obj.Like+=1
obj.save()
return JsonResponse({'success':True,'content':'Like','Like':obj.Like})
def dislike_this_movie(request,key):
obj=Movies.objects.get(pk=key)
obj.Dislike+=1
obj.save()
return JsonResponse({'success':True,'content':'Dislike','Dislike':obj.Dislike})
urls.py,
urlpatterns=[
path('<int:key>/like',like_this_movie,name='like'),
path('<int:key>/dislike',dislike_this_movie,name='dislike')
]
detail.js
document.addEventListener('DOMContentLoaded',()=>{
document.querySelector('#likebtn').onclick=()=>{
const request=new XMLHttpRequest;
request.open('GET','like',true);
console.log(request);
request.onload=()=>{
const data = JSON.parse(request.responseText);
if ((data.success)&&(data.content=='Like')){
totalLike=data.Like;
likespan=document.querySelector('#likespan');
likespan.innerHTML=totalLike;
likebtn=document.querySelector('#likebtn');
likebtn.disabled = true;
dislikebtn.disabled=true;
}
}
request.send();
return false;
}
document.querySelector('#dislikebtn').onclick=()=>{
const request=new XMLHttpRequest;
request.open('GET','dislike',true);
request.onload=()=>{
const data = JSON.parse(request.responseText);
if ((data.success)&&(data.content=='Dislike')){
totalDislike=data.Dislike;
dislikespan=document.querySelector('#dislikespan');
dislikespan.innerHTML=totalDislike;
dislikebtn=document.querySelector('#dislikebtn');
dislikebtn.disabled = true;
likebtn.disabled=true;
}
}
request.send();
return false;
}
})
detail.html,
<h4>
<span id="likespan">{{object.Like}}</span>
<button id="likebtn" type="submit" class="btn btn-primary">Like</button>
<span id="dislikespan">{{object.Dislike}}</span>
<button id="dislikebtn" type="submit" class="btn btn-primary">Dislike</button>
</h4>
So I have a page where multiple articles are listed. (To be precise, TITLES that are outlinked to the articles written on Notion template.) And I want to have a filed in my model that counts the number of clicks of each article. (I don't want to use django-hitcount library).
Let me first show you my code. models.py
class Article(models.Model):
number = models.IntegerField(primary_key=True)
title = models.CharField(max_length=20, default="")
url = models.URLField(max_length=100, default="")
hits = models.IntegerField(default=0)
template
...
<div class="col text-center">
{% for q in allArticles %}
<h2 id={{q.number}}>{{q.title}}</h2>
{% endfor %}
</div>
...
I was thinking of using onclick() event in JavaScript, but then passing data from JavaScript to Django seemed too challenging to me at the moment.
I'd very much appreciate your help. Thanks.
Well, when you dont take up new challenges you stop learning !
The onclick method looks like the best imo, lets see what others suggest.
honestly, using JS and AJAX to communicate with your django server might be dauting at first but it is quite easy really.
if you know how to create a function in your views.py and know a bit of JS, it's just like any other classic functionnality.
Set up your urls.py for the view function that will add a click to the counter:
path('ajax/add_click', views.add_click name="add_click"),
Then, create your view function (pseudo code):
def add_click(request):
# retrieve the article
article_id = request.GET.get("articleId", None)
# then retrieve the object in database, add 1 to the counter save and return a response
Now the "complicated" part, the ajax request:
function add_one_click(articleId) {
$.ajax({
type: "GET",
url: '/ajax/add_click', // you also can use {% url "app_name:add_click" %}
data: {
'articleId': articleId,
},
success: function() {
console.log("hit added to article");
}
});
}
You need to add JS and Ajax lib to your html template for it to works.
Also you need to pass in the onclick attribute the name of the function + the id of the article
onclick="add_one_click({{article.id}})"
One more thing, this type of view, if not protected can lead to get false results.
Instead of having q.url have a new URL(/article_count?id=q.id) which you will define on your Django project
def article_count(req):
_id = req.GET.get('id', '')
# Query Aritcle and get object
q = Article.objects.get(id=_id)
# update the fields for clicks
q.hits += 1
q.save()
# redirect the page
return redirect(q.url)
Edit:
Create a new url that would handle your article click, lets say-
path('article/clicked/<article_number>', views.click_handler, name='click_counter')
Now, in your template use this url for all the article
<div class="col text-center">
{% for q in allArticles %}
<h2 id={{q.number}}>{{q.title}}</h2>
{% endfor %}
</div>
and in your views.py create a new controller
def click_handler(request, article_number):
article = Article.objects.get(number=article_number)
article.hits += 1
article.save()
# now redirect user to the outer link
return redirect(article.url)
I have a Post model that requires a certain category before being added to the database, and I want the category to be generated automatically. Clicking the addPost button takes you to a different page and so the category will be determined by taking a part of the previous page URL.
Is there a way to get the previous page URL as a string?
I have added my AddPost button here.
<aside class="addPost">
<article>
<form action="/Forum/addPost">
<input type="submit" name="submit" value="Add Post"/>
</form>
</article>
</aside>
You can do that by using request.META['HTTP_REFERER'], but it will exist if only your tab previous page was from your website, else there will be no HTTP_REFERER in META dict. So be careful and make sure that you are using .get() notation instead.
# Returns None if user came from another website
request.META.get('HTTP_REFERER')
Note: I gave this answer when Django 1.10 was an actual release. I'm not working with Django anymore, so I can't tell if this applies to Django 2
You can get the referring URL by using request.META.HTTP_REFERER
More info here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
I can't answer #tryingtolearn comment, but for future people, you can use request.META['HTTP_REFERER']
Instead of adding it to your context, then passing it to the template, you can place it in your template directly with:
Return
A much more reliable method would be to explicitly pass the category in the URL of the Add Post button.
You can get the previous url in "views.py" as shown below:
# "views.py"
from django.shortcuts import render
def test(request):
pre_url = request.META.get('HTTP_REFERER') # Here
return render(request, 'test/index.html')
You can also get the previous url in Django Template as shown below:
# "index.html"
{{ request.META.HTTP_REFERER }}