How can I print query set element in Django Template? - python

I have this code in my template file
{{markets|getSpiderItem:spider.id}}
Mysql has market_timezone and market_location and it connects to another table with spider_id so I filtered as follow:
#register.filter
def getSpiderItem(datas, spider_id):
return datas.filter(spider=spider_id)
I am getting this output:
<QuerySet [{'market_timezone': 'Turkey', 'market_location': 'Nigde'}]>
I want to print this QuerySet item on Django Template separately.
This function has already 2 for loop so I want to print just 1 time. I don't wanna use for loop like this:
{% for market in markets|getSpiderItem:spider.id %}
I want something like this but I couldn't figure out:
For Example:
{{markets|getSpiderItem:spider.id|market_timezone}} # I don't know the true way.

this is ok
{{markets|getSpiderItem:spider.id|market_timezone}}
modify getSpiderItem()
#register.filter
def getSpiderItem(datas, spider_id):
return iter(datas.filter(spider=spider_id))
define filter market_timezone():
#register.filter
def market_timezone(iitem):
return next(iitem).market_timezone
Expected content: Turkey

Related

Django Database get data

I am trying to get all my data out of the database in a array or list format.
Such that I can make an for loop in the html to loop through all the names in the database.
I tried with:
all_name = name.objects.all()
the output will be shown as
<QuerySet [<allName: name1>, < allName: name2>, < allName: name3>]>
However I want to get something like:
name1;
name2; name3
What I did next is to use the .get function:
all_name = name.objects.get(id=1)
my name model:
class name(models.Model):
firstname = models.CharField(max_length=100)
def __str__(self):
return (self.firstname)
This gives me only one object with the given id.
Is there a way to get what I am looking for and display my array/list with a forloop in a html file?
You can simply try for Name model with consider allName as a attribute/column
list(Name.objects.all().values_list('allName', flat=True))
or
Name.objects.all().values_list('allName')
You can join the strings that originate from the database with:
'; '.join(map(str, name.objects.all()))
Many:
name_list = Name.objects.all().values_list('firstname', flat=True))
One:
query = name.objects.get(id=1)
name = query.firstname

Getting a list from URL with a regular expression django

I have the following view for filter Order objects based on a list of ids:
class GetOrdersByIDs(generics.ListAPIView):
serializer_class = OrderSerializer
def get_queryset(self):
print(self)
ids = self.kwargs.get('ids')
return Order.objects.filter(id__in=ids)
I want to receive a list of ids from URL like this: myurl/ids/1,2,3,4, but I think I have to use a regular expression like this \d+(,\d+)*$, but I don't know how to get a list from this.
I think you should use query_param for this. sth like: .../?id=1&id=2&id=3.
Then when you use request.GET.getlist('id'), it will return you a list like [1,2,3]:
...
def get_queryset(self):
ids = self.request.GET.getlist('id')
return Order.objects.filter(id__in=ids)

How to create a custom generic view from a web2py RESTFUL service?

Using Web2Py RESTFUL services, I'd like the following html to render in the browser after navigating to this link (http://127.0.0.1:8000/app/default/api/example_data.html_table/?limit=1):
<div><table><thead><tr><th>example_data.id</th><th>example_data.Firstname</th><th>example_data.Lastname</th><th>example_data.Age</th></tr></thead><tbody><tr class="w2p_odd odd"><td>1</td><td>SUUUUPPPEEEERRRR LONGGGGG FIRSTTTT NAMEEEE</td><td>Smith</td><td>1</td></tr></tbody></table></div>
However, I currently receive the following:
<div><table><thead><tr><th>example_data.id</th><th>example_data.Firstname</th><th>example_data.Lastname</th><th>example_data.Age</th></tr></thead><tbody><tr class="w2p_odd odd"><td>1</td><td>SUUUUPPPEEEER...</td><td>Smith</td><td>1</td></tr></tbody></table></div>
The difference is that Web2Py is shortening "SUUUUPPPEEEERRRR LONGGGGG FIRSTTTT NAMEEEE" to "SUUUUPPPEEEER..." but I need the entire text
My View called generic.html_table that generates this is the following:
{{=BEAUTIFY(response._vars[next(iter(response._vars))])}}
Controller
#request.restful()
def api():
response.view = 'generic.' + request.extension
def GET(*args,**vars):
patterns = 'auto'
parser = db.parse_as_rest(patterns,args,vars)
return dict(content=parser.response)
def POST(table_name,**vars):
if 'id' in vars.keys():
return db[table_name].update_or_insert(db[table_name]._id == vars['id'],**vars)
else:
return db[table_name].validate_and_insert(**vars)
def PUT(table_name,**vars):
record_id = vars['id']
return db(db[table_name]._id==record_id).update(**vars)
def DELETE(table_name,record_id):
return db(db[table_name]._id==record_id).delete()
return dict(GET=GET, POST=POST, PUT=PUT, DELETE=DELETE)
MODEL
db.define_table('example_data', Field('Firstname', 'string'),Field('Lastname', 'string'),Field('Age', 'integer'))
I've also tried the following views:
{{=response._vars[next(iter(response._vars))]}}
RESULT (first name still cut off):
<table><thead><tr><th>example_data.id</th><th>example_data.Firstname</th><th>example_data.Lastname</th><th>example_data.Age</th></tr></thead><tbody><tr class="w2p_odd odd"><td>1</td><td>Jill</td><td>Smith</td><td>1</td></tr><tr class="w2p_even even"><td>2</td><td>Eve</td><td>Jackson</td><td>33</td></tr><tr class="w2p_odd odd"><td>3</td><td>afdaskfdlasjf...</td><td>Jackson</td><td>33</td></tr><tr class="w2p_even even"><td>4</td><td>SUUUUPPPEEEER...</td><td>Jackson</td><td>33</td></tr></tbody></table>
I've also tried the following views:
{{=XML(response._vars[next(iter(response._vars))])}}
RESULT (Lost all HTML formatting):
example_data.id,example_data.Firstname,example_data.Lastname,example_data.Age
1,Jill,Smith,1
2,Eve,Jackson,33
3,afdaskfdlasjfkdlsjfklajdfskasjfklsdajfdklsajfklsajfdskalfdjsakldfjklasfjkdlsajfdsakljdklsadcjklasjcklsjackldsjakfldajsfklasdfjklasjfdklajfdsklsjafkldasjfkldasjkldsjcklajsckljackldajsdfklfjkalsncklacnkalsdfjkldasnckldasjckljsdaklfdnfkldsajfdklasjldsk,Jackson,33
4,SUUUUPPPEEEERRRR LONGGGGG FIRSTTTT NAMEEEE,Jackson,33
All of those methods ultimately result in the DAL Rows object being passed to SQLTABLE for rendering in the view. By default, fields are truncated to 16 characters. If you want to change that, you will have to call SQLTABLE explicitly:
{{=SQLTABLE(content, truncate=100)}}

How to parse out {'value__avg': 46.26524716693248} 'value_avg' when using aggregate(Avg()) in django

I am using django here is my model:
class Location(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=50)
altitude = models.IntegerField(max_length=10000)
area = models.ForeignKey('Area')
def __str__(self):
return str(self.area) + ':' + str(self.name)
#measurement.id value date location
class Measurement(models.Model):
id = models.IntegerField(primary_key=True)
value = models.FloatField(max_length=50)
data = models.DateTimeField()
location = models.ForeignKey('Location')
def __str__(self):
return "measurement#"+str(Location.objects.filter(id=self.id))
My HTML page is showing {'value__avg': 46.26524716693248} when it should just show 46.265.
Heres my function:
#property
def average_measurement(self):
locations = Location.objects.filter(area__name=self.name)
return Measurement.objects.filter(location__in=locations).aggregate(Avg('value'))
so how do I get the ugly part out?
aggregate() returns a dictionary where the key is combined from the grouping keys and grouping function name, you can just get the value by key:
return Measurement.objects.filter(location__in=locations).aggregate(Avg('value'))["value__avg"]
Or, if needed, you can also do that in the template using the dot-notation:
{{ obj.average_measurement.value__avg }}
You can also preset the key name with your own value:
return Measurement.objects.filter(location__in=locations).aggregate(my_average=Avg('value'))
Then, you would access it as:
{{ obj.average_measurement.my_average }}
That's not the ugly part, it's expected output and you need to understand what does the output mean. When you do django Aggregation, it returns a dictionary-like object with your aggregation criteria as keys and results as values.
What you need to do is to access it like a dictionary in template to extract the values:
{% for item in items %}
{{ item.value__avg|floatformat:3 }}
{% endfor %}
Check django doc about what is the lookup sequence for dot in template.
Also checkout django doc about aggreate function call.
Also checkout django doc about floatformat template filter.

change url title if id changes - django

I have
def newsprofile(request, newstitle, newsid):
newsobj = get_object_or_404(NewsModel, pk=int(newsid))
return render(request, 'newsprofile.html', {'newsobj': newsobj})
but now, if I change the id 1 to 2 in url inside adressbar and hit the enter button e.g. /sometitle_and_and_blabla/1/,
i will get another news but the title doesnot change, it only becomes like:
/sometitle_and_and_blabla/2/
How can I change the title also if id changes?
the urls.py looks like this:
url(r'^news/(?P<newstitle>[^\/]*)/(?P<newsid>\d+)/$', 'newsprofile', name='newsprofile'),
Try like this,
def newsprofile(request, newstitle, newsid):
newsobj = get_object_or_404(NewsModel, pk=int(newsid))
if newstitle != newsobj.newstitle:
return HttpResponsePermanentRedirect('/%s/%s/' % (newsobj.newstitle, newsid))
.....
As you are using named urls (e.g. newsprofile) I recommend the following solution. This is flexible and easy to maintain, even if your urls change as long as you use the same url parameters:
from django.http import HttpResponseRedirect
...
def newsprofile(request, newstitle, newsid):
newsobj = get_object_or_404(NewsModel, pk=int(newsid))
if newsobj.newstitle != newstitle:
return HttpResponseRedirect(reverse("newsprofile", args=[newstitle, newsid]))
return render(request, 'newsprofile.html', {'newsobj': newsobj})
See Django docs here for reverse resolution of URLs.

Categories

Resources