From 6378aa501dace057bd8f950ef6dd116f4c51f475 Mon Sep 17 00:00:00 2001 From: Won Yang Date: Mon, 21 Jun 2021 09:16:32 -0500 Subject: [PATCH] adds solution --- ormQueries/products/models.py | 3 +- ormQueries/products/product_crud.py | 93 ++++++++++++++++++++++++++++- ormQueries/products/tests.py | 20 ++++--- 3 files changed, 106 insertions(+), 10 deletions(-) diff --git a/ormQueries/products/models.py b/ormQueries/products/models.py index 8853227..be72320 100644 --- a/ormQueries/products/models.py +++ b/ormQueries/products/models.py @@ -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) diff --git a/ormQueries/products/product_crud.py b/ormQueries/products/product_crud.py index 0d8c549..a325448 100644 --- a/ormQueries/products/product_crud.py +++ b/ormQueries/products/product_crud.py @@ -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')) diff --git a/ormQueries/products/tests.py b/ormQueries/products/tests.py index 298ba56..a09b6cd 100644 --- a/ormQueries/products/tests.py +++ b/ormQueries/products/tests.py @@ -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'] @@ -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]) @@ -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"""