I've got a query...
packages = Package.objects.annotate(bid_count=Count('items__bids'))
Which is supposed to give me a list of packages with the number of bids each. It works great if there's only one item in the package, but if there's more it double counts.
Each package consists of 1 or more items. Each bid is placed on 1 or more items within a package. I want to retrieve the number of bids placed on the items within that package.
If there is 1 bid placed on 2 items within a package, presently this will count as 2, I want it to return 1.
I tried Count('items__bids__distinct') but that didn't work. How can I do this?
I had the same problem and I found the resolution:
packages = Package.objects.annotate(bid_count=Count('items__bids', distinct = True))
Related
I'm using Django with Postgres.
On a page I can show a list of featured items, let's say 10.
If in the database I have more featured items than 10, I want to get them random/(better rotate).
If the number of featured item is lower than 10, get all featured item and add to the list until 10 non-featured items.
Because the random takes more time on database, I do the sampling in python:
count = Item.objects.filter(is_featured=True).count()
if count >= 10:
item = random.sample(list(Item.objects.filter(is_featured=True))[:10])
else:
item = list(Item.objects.all()[:10])
The code above miss the case where there less than 10 featured(for example 8, to add 2 non-featured).
I can try to add a new query, but I don't know if this is an efficient retrive, using 4-5 queries for this.
The best solution I could find is this:
from itertools import chain
items = list(chain(Item.objects.filter(is_featured=True).order_by('?'), Item.objects.filter(is_featured=False).order_by('?')))[:10]
In this way, the order of the querysets are retained, but downside is that items becomes a list not a Queryset. You can see more details in this SO Answer. FYI: there are some fantastic solutions like using Q or pipe but they don't retain order of queryset.
SQL method: You can achieve that with an SQL statement like this:
SELECT uuid_generate_v4(), *
FROM table_name
ORDER BY NOT is_featured, uuid_generate_v4()
LIMIT 10;
Explain: The generated UUID should simulate randomness (for the purpose of e-commerce, this should suffice). While sorting the rows by NOT is_featured will put the is_featured rows on top; and automatically flow the rows down to 10 limits if it run out of featured items.
I have a dynamodb table. And I want to build a page where I can see the items in the table. But since this could have tens of thousand of items, I want to see them in 10 items per page. How do I do that? How to scan items 1000 to 2000?
import boto
db = boto.connect_dynamodb()
table = db.get_table('MyTable')
res = table.scan(attributes_to_get=['id'], max_results=10)
for i in res:
print i
What do you mean by 1000~2000 items?
There is no global order of hash keys (primary or index), thus it's hard to define the 10000~20000 items in advance.
However, it makes perfect sense if you'd like to find the next 1000 items, given the last return item. To fetch the next page, you execute the scan method again by providing the primary key value of the last item in the previous page so that the scan method can return the next set of items. The parameter name is exclusive_start_key and its initial value is None.
See more details in official docs.
I have a spider where the scraped items are 3: brand, model and price from the same page.
Brands and models are using the same sel.xpath, later extracted and differentiated by .re in loop. However, price item is using different xpath. How can I use or combine two XPathSelectors in the spider?
Examples:
for brand and model:
titles = sel.xpath('//table[#border="0"]//td[#class="compact"]')
for prices:
prices = sel.xpath('//table[#border="0"]//td[#class="cl-price-cont"]//span[4]')
Tested and exported individually by xpath. My problem is the combining these 2 to construct the proper loop.
Any suggestions?
Thanks!
Provided you can differentiate all 3 kind of items (brand, model, price) later, you can try using XPath union (|) to bundle both XPath queries into one selector :
//table[#border="0"]//td[#class="compact"]
|
//table[#border="0"]//td[#class="cl-price-cont"]//span[4]
UPDATE :
Responding your comment, above meant to be single XPath string. I'm not using python, but I think it should be about like this :
sel.xpath('//table[#border="0"]//td[#class="compact"] | //table[#border="0"]//td[#class="cl-price-cont"]//span[4]')
I believe you are having trouble associating the price with the make/model because both xpaths give you a list of all numbers, correct? Instead, what you want to do is build an xpath that will get you each row of the table. Then, in your loop, you can do further xpath queries to pull out the make/model/price.
rows = sel.xpath('//table[#border="0"]/tr') # Get all the rows
for row in rows:
make_model = row.xpath('//td[#class="compact"]/text()').extract()
# set make and model here using your regex. something like:
(make,model) = re("^(.+?)\s(.+?)$", make_model).groups()
price = row.xpath('//td[#class="cl-price-cont"]//span[4]/text()').extract()
# do something with the make/model/price.
This way, you know that in each iteration of the loop, the make/model/price you're getting all go together.
I have three models, Which has some common but not exact fields, from a single view ex. home I am retrieving like this
interviews = Interviews.objects.all().order_by('pub_date')[:3]
publications = Publications.objects.all().order_by('pub_date')[:3]
published = Published.objects.all().order_by('pub_date')[:3]
From home view I want them to show in template in such order that all the latest/New entries associated with these models will be in top.
like if interview entry 10 is the most recent entry in these all models, then it will be first, then if the published one is second recent it will be second ... etc .etc
Can any one tell me how to do it?
Depending on your other requirements it may be a good idea to make them into sublcasses of a common superclass - containing the common elements.
It's hard to say if it's valid, but if you do you can query the different types of objects separately or together by calling
SuperClass.objects.all().order_by('-pub_date')[:9]
which will render the 9 first objects regerdless of what sublcass they are. Of course assuming the superclass is named SuperClass. Of course this does not insure that there are 3 of each model.
Another simple way of solving it - although admittedly not using a query would simply be to sort the lists.
entries = sorted(list(interviews) + list(publications) + list(published), key=lambda x: x.pub_date, reverse=True)
should work - basically turning them into lists and sorting them.
One possible way is using lambda to sort data, but costs are hiher since you will doing this to python, not DBMS...
lst = []
lst.extend(list(Interviews.objects.order_by('pub_date')[:10]))
lst.extend(list(Publications.objects.order_by('pub_date')[:10]))
lst.extend(list(Published.objects.order_by('pub_date')[:10]))
# take 10 records for each, since you could not know how many records will be picked from which table
# now order them...
lst.sort(lambda x, y: cmp(x.pub_date, y.pub_date))
# and reverse the order, so newset is the first...
lst.reverse()
this will give you a list of objects ordered py pub_date, so you can slice the final list to get any number of records you want...
lst = lst[:10]
I'm using django-filter to drill down and would like to create breadcrumbs for each item that was filtered. For example:
Price ranges:
10,000+
5,000-9,999
1,000-4,999
0-999
Bedrooms:
4
3
2
1
Each of the items under Price ranges and Bedrooms would be a link to drill down in a queryset.
I'd like to create a breadcrumb such as Price range 0-999 or Bedrooms 3 if the user were to click those links, and then show Price range 0-999 > Bedrooms 3 or Bedrooms 3 > Price range 0-999 when they click a second link.
The breadcrumbs should maintain order (the part I'm having trouble with) and work for any number of attributes. Clicking a link in the breadcrumb trail should apply the filter clicked on and all filters before it in the trail.
I'd like to create an empty QueryDict and then iterate through request.GET to build the QueryDict up as I output the breadcrumbs, but for some reason QueryDict iterates through its elements backwards (see the documentation).
What's the cleanest way to accomplish this? Does anyone know why QueryDict works this way? (I imagine there's a use-case I'm missing.) Any advice is appreciated.
keep track of the order in sessions. so when the first filter is clicked (eg 3 beds) store it. then if another one is clicked, build your bread crumbs from sessions. say the second one was 0-999 you'd pull any existing breadcrumbs (in this example you'd find the 3 beds) and then tack on the latest (0-999).