Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Won Django Queries Solution #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ormQueries/products/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.db import models
from datetime import datetime
from datetime import datetime
from django.utils import timezone


class Product(models.Model):
manufacturer = models.CharField(max_length=200, null=True)
model = models.CharField(max_length=200, null=True)
Expand Down
93 changes: 91 additions & 2 deletions ormQueries/products/product_crud.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,95 @@
from .models import Product
from .models import Product
from django.db.models import Q, Avg, Max
from django.db.models.functions import Length


class ProductCrud:
@classmethod
def get_all_products(cls):
pass
return Product.objects.all()

@classmethod
def find_by_model(cls, model_name):
return Product.objects.get(model=model_name)

@classmethod
def last_record(cls):
return Product.objects.last()

@classmethod
def by_rating(cls, rating):
return Product.objects.filter(rating=rating)

@classmethod
def by_rating_range(cls, start, end):
return Product.objects.filter(rating__range=(start, end))

@classmethod
def by_rating_and_color(cls, rating, color):
rating_matches = Product.objects.filter(rating=rating)
color_matches = Product.objects.filter(color=color)
return rating_matches.intersection(color_matches)

@classmethod
def by_rating_or_color(cls, rating, color):
rating_matches = Product.objects.filter(rating=rating)
color_matches = Product.objects.filter(color=color)
return rating_matches.union(color_matches)

@classmethod
def no_color_count(cls):
return Product.objects.filter(color=None).count()

@classmethod
def below_price_or_above_rating(cls, price_cents, rating):
# using .union()
# below_price_set = Product.objects.filter(
# price_cents__lt=price_cents)
# above_rating_set = Product.objects.filter(rating__gt=rating)
# return (below_price_set.union(above_rating_set)).order_by('id')

# using Q objects
return Product.objects.filter(Q(price_cents__lt=price_cents) | Q(rating__gt=rating))

@classmethod
def ordered_by_category_alphabetical_order_and_then_price_decending(cls):
return Product.objects.order_by('category', '-price_cents')

@classmethod
def products_by_manufacturer_with_name_like(cls, manufacturer_name):
return Product.objects.filter(manufacturer__contains=manufacturer_name)

@classmethod
def manufacturer_names_for_query(cls, manufacturer_name):
# flat=True returns single values, not tuples
return Product.objects.filter(manufacturer__contains=manufacturer_name).values_list('manufacturer', flat=True)

@classmethod
def not_in_a_category(cls, category):
return Product.objects.exclude(category=category)

@classmethod
def limited_not_in_a_category(cls, category, limit):
return Product.objects.exclude(category=category)[0:limit]

@classmethod
def category_manufacturers(cls, category):
return Product.objects.filter(category=category).values_list('manufacturer', flat=True)

@classmethod
def average_category_rating(cls, category):
return Product.objects.filter(category=category).aggregate(Avg('rating'))

@classmethod
def greatest_price(cls):
return Product.objects.aggregate(Max('price_cents'))

@classmethod
def longest_model_name(cls):
# orders objects by the length of model, descending (hence the '-')
# gets the longest model name queryset and returns the id of that
return Product.objects.order_by(-Length('model'))[0].id

@classmethod
def ordered_by_model_length(cls):
return Product.objects.order_by(Length('model'))
20 changes: 13 additions & 7 deletions ormQueries/products/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
from .models import Product
from .product_crud import ProductCrud


def get_query_ids(queryset):
return list(queryset.values_list('id', flat=True))


class ProductCrudTestCase(TestCase):
fixtures = ['products.yaml']

Expand Down Expand Up @@ -46,7 +48,7 @@ def test_06_by_rating_and_color(self):

def test_07_by_rating_or_color(self):
"""finds products by a rating or color value"""
product_crud = ProductCrud.by_rating_or_color(4.3 , 'blue')
product_crud = ProductCrud.by_rating_or_color(4.3, 'blue')
product_ids = get_query_ids(product_crud)
self.assertEquals(product_ids, [5, 15])

Expand All @@ -64,35 +66,39 @@ def test_10_ordered_by_category_alphabetical_order_and_then_price_decending(self
"""returns products ordered by category alphabetical and decending price"""
product_crud = ProductCrud.ordered_by_category_alphabetical_order_and_then_price_decending()
product_ids = get_query_ids(product_crud)
self.assertEquals(product_ids, [1, 18, 10, 27, 29, 21, 9, 7, 15, 5, 19, 8, 4, 30, 14, 22, 16, 13, 26, 3, 28, 23, 24, 25, 17, 12, 2, 20, 11, 6])
self.assertEquals(product_ids, [1, 18, 10, 27, 29, 21, 9, 7, 15, 5, 19,
8, 4, 30, 14, 22, 16, 13, 26, 3, 28, 23, 24, 25, 17, 12, 2, 20, 11, 6])

def test_11_products_by_manufacturer(self):
"""returns products made by manufacturers with names containing an input string"""
product_crud = ProductCrud.products_by_manufacturer_with_name_like('Group')
product_crud = ProductCrud.products_by_manufacturer_with_name_like(
'Group')
product_ids = get_query_ids(product_crud)
self.assertEquals(product_ids, [2, 3, 6, 29])

def test_12_manufacturer_names_for_query(self):
"""returns a list of manufacturer names that match query"""
product_crud = ProductCrud.manufacturer_names_for_query('Group')
self.assertCountEqual(product_crud, ["Lakin Group", "Nikolaus Group","Rolfson Group", "Watsica Group"])
self.assertCountEqual(product_crud, [
"Lakin Group", "Nikolaus Group", "Rolfson Group", "Watsica Group"])

def test_13_not_in_a_category(self):
"""returns products that are not in a category"""
product_crud = ProductCrud.not_in_a_category('Garden')
product_ids = get_query_ids(product_crud)
self.assertEquals(product_ids, list(range(1,30)))
self.assertEquals(product_ids, list(range(1, 30)))

def test_14_limited_not_in_a_category(self):
"""returns products that are not in a category up to a limit"""
product_crud = ProductCrud.limited_not_in_a_category('Garden', 3)
product_ids = get_query_ids(product_crud)
self.assertEquals(product_ids, [1, 2, 3 ])
self.assertEquals(product_ids, [1, 2, 3])

def test_15_category_manufacturers(self):
"""returns an array of manufacturers for a category"""
product_crud = ProductCrud.category_manufacturers('Baby')
self.assertCountEqual(product_crud,["Cormier, Rice and Ledner", "Crooks, Pacocha and Rohan","Howell, Hills and Dickens", "Muller-Koss", "Rolfson Group"])
self.assertCountEqual(product_crud, [
"Cormier, Rice and Ledner", "Crooks, Pacocha and Rohan", "Howell, Hills and Dickens", "Muller-Koss", "Rolfson Group"])

def test_16_average_category_rating(self):
"""returns the average"""
Expand Down