mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
Fix after rebase
This commit is contained in:
@@ -83,6 +83,11 @@ class Migration(migrations.Migration):
|
||||
name='ingredient',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.ingredient'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shoppinglistrecipe',
|
||||
name='name',
|
||||
field=models.CharField(blank=True, default='', max_length=32),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='shoppinglistentry',
|
||||
name='unit',
|
||||
|
||||
@@ -822,7 +822,7 @@ class ShoppingListRecipe(ExportModelOperationsMixin('shopping_list_recipe'), mod
|
||||
|
||||
|
||||
class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), models.Model, PermissionModelMixin):
|
||||
list_recipe = models.ForeignKey(ShoppingListRecipe, on_delete=models.CASCADE, null=True, blank=True) # TODO remove when shoppinglist is deprecated
|
||||
list_recipe = models.ForeignKey(ShoppingListRecipe, on_delete=models.CASCADE, null=True, blank=True, related_name='entries')
|
||||
food = models.ForeignKey(Food, on_delete=models.CASCADE)
|
||||
unit = models.ForeignKey(Unit, on_delete=models.SET_NULL, null=True, blank=True)
|
||||
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE, null=True, blank=True)
|
||||
|
||||
@@ -3,10 +3,11 @@ from rest_framework.schemas.utils import is_list_view
|
||||
|
||||
|
||||
class QueryParam(object):
|
||||
def __init__(self, name, description=None, qtype='string'):
|
||||
def __init__(self, name, description=None, qtype='string', required=False):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.qtype = qtype
|
||||
self.required = required
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.name}, {self.qtype}, {self.description}'
|
||||
@@ -19,7 +20,7 @@ class QueryParamAutoSchema(AutoSchema):
|
||||
parameters = super().get_path_parameters(path, method)
|
||||
for q in self.view.query_params:
|
||||
parameters.append({
|
||||
"name": q.name, "in": "query", "required": False,
|
||||
"name": q.name, "in": "query", "required": q.required,
|
||||
"description": q.description,
|
||||
'schema': {'type': q.qtype, },
|
||||
})
|
||||
|
||||
@@ -36,12 +36,17 @@ class ExtendedRecipeMixin(serializers.ModelSerializer):
|
||||
except KeyError:
|
||||
api_serializer = None
|
||||
# extended values are computationally expensive and not needed in normal circumstances
|
||||
if self.context.get('request', False) and bool(int(self.context['request'].query_params.get('extended', False))) and self.__class__ == api_serializer:
|
||||
return fields
|
||||
else:
|
||||
try:
|
||||
if bool(int(self.context['request'].query_params.get('extended', False))) and self.__class__ == api_serializer:
|
||||
return fields
|
||||
except (AttributeError, KeyError) as e:
|
||||
pass
|
||||
try:
|
||||
del fields['image']
|
||||
del fields['numrecipe']
|
||||
return fields
|
||||
except KeyError:
|
||||
pass
|
||||
return fields
|
||||
|
||||
def get_image(self, obj):
|
||||
# TODO add caching
|
||||
@@ -286,8 +291,9 @@ class KeywordSerializer(UniqueFieldsMixin, ExtendedRecipeMixin):
|
||||
class Meta:
|
||||
model = Keyword
|
||||
fields = (
|
||||
'id', 'name', 'icon', 'label', 'description', 'image', 'parent', 'numchild', 'numrecipe')
|
||||
read_only_fields = ('id', 'label', 'image', 'parent', 'numchild', 'numrecipe')
|
||||
'id', 'name', 'icon', 'label', 'description', 'image', 'parent', 'numchild', 'numrecipe', 'created_at',
|
||||
'updated_at')
|
||||
read_only_fields = ('id', 'label', 'numchild', 'parent', 'image')
|
||||
|
||||
|
||||
class UnitSerializer(UniqueFieldsMixin, ExtendedRecipeMixin):
|
||||
@@ -368,15 +374,6 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
|
||||
def get_shopping_status(self, obj):
|
||||
return ShoppingListEntry.objects.filter(space=obj.space, food=obj, checked=False).count() > 0
|
||||
|
||||
def get_fields(self, *args, **kwargs):
|
||||
fields = super().get_fields(*args, **kwargs)
|
||||
print('food', self.__class__, self.parent.__class__)
|
||||
# extended values are computationally expensive and not needed in normal circumstances
|
||||
if not bool(int(self.context['request'].query_params.get('extended', False))) or not self.parent:
|
||||
del fields['image']
|
||||
del fields['numrecipe']
|
||||
return fields
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data['name'] = validated_data['name'].strip()
|
||||
validated_data['space'] = self.context['request'].space
|
||||
@@ -633,6 +630,7 @@ class MealPlanSerializer(SpacedModelSerializer, WritableNestedModelSerializer):
|
||||
read_only_fields = ('created_by',)
|
||||
|
||||
|
||||
# TODO deprecate
|
||||
class ShoppingListRecipeSerializer(serializers.ModelSerializer):
|
||||
name = serializers.SerializerMethodField('get_name') # should this be done at the front end?
|
||||
recipe_name = serializers.ReadOnlyField(source='recipe.name')
|
||||
@@ -698,8 +696,8 @@ class ShoppingListEntrySerializer(WritableNestedModelSerializer):
|
||||
def run_validation(self, data):
|
||||
if (
|
||||
data.get('checked', False)
|
||||
and not (id := data.get('id', None))
|
||||
and not ShoppingListEntry.objects.get(id=id).checked
|
||||
and self.root.instance
|
||||
and not self.root.instance.checked
|
||||
):
|
||||
# if checked flips from false to true set completed datetime
|
||||
data['completed_at'] = timezone.now()
|
||||
@@ -711,20 +709,6 @@ class ShoppingListEntrySerializer(WritableNestedModelSerializer):
|
||||
if 'completed_at' in data:
|
||||
del data['completed_at']
|
||||
|
||||
############################################################
|
||||
# temporary while old and new shopping lists are both in use
|
||||
try:
|
||||
# this serializer is the parent serializer for the API
|
||||
api_serializer = self.context['view'].serializer_class
|
||||
except Exception:
|
||||
# this serializer is probably nested or a foreign key
|
||||
api_serializer = None
|
||||
if self.context['request'].method == 'POST' and not self.__class__ == api_serializer:
|
||||
data['space'] = self.context['request'].space.id
|
||||
data['created_by'] = self.context['request'].user.id
|
||||
############################################################
|
||||
if self.context['request'].method == 'POST' and self.__class__ == api_serializer:
|
||||
data['created_by'] = {'id': self.context['request'].user.id}
|
||||
return super().run_validation(data)
|
||||
|
||||
def create(self, validated_data):
|
||||
|
||||
@@ -119,8 +119,13 @@ def test_delete(u1_s1, u1_s2, obj_1):
|
||||
assert r.status_code == 204
|
||||
|
||||
|
||||
# test sharing
|
||||
# test completed entries still visible if today, but not yesterday
|
||||
# test create shopping list from recipe
|
||||
# test create shopping list from mealplan
|
||||
# test create shopping list from recipe, excluding ingredients
|
||||
# TODO test sharing
|
||||
# TODO test completed entries still visible if today, but not yesterday
|
||||
# TODO test create shopping list from recipe
|
||||
# TODO test delete shopping list from recipe - include created by, shared with and not shared with
|
||||
# TODO test create shopping list from food
|
||||
# TODO test delete shopping list from food - include created by, shared with and not shared with
|
||||
# TODO test create shopping list from mealplan
|
||||
# TODO test create shopping list from recipe, excluding ingredients
|
||||
# TODO test auto creating shopping list from meal plan
|
||||
# TODO test excluding on-hand when auto creating shopping list
|
||||
|
||||
Reference in New Issue
Block a user