model migrations
This commit is contained in:
@ -1,58 +0,0 @@
|
|||||||
# Generated by Django 3.2.7 on 2021-10-01 20:52
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import django.utils.timezone
|
|
||||||
|
|
||||||
|
|
||||||
def copy_values_to_sle(apps, schema_editor):
|
|
||||||
ShoppingListEntry = apps.get_model('app', 'ShoppingListEntry')
|
|
||||||
db_alias = schema_editor.connection.alias
|
|
||||||
from django.db.models import F
|
|
||||||
MetaDataValue.objects.using(db_alias).all().update(
|
|
||||||
short_value=F('shoppinglist__created_by')
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('cookbook', '0157_alter_searchpreference_trigram'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='food',
|
|
||||||
name='on_hand',
|
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='shoppinglistentry',
|
|
||||||
name='completed_at',
|
|
||||||
field=models.DateTimeField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='shoppinglistentry',
|
|
||||||
name='created_at',
|
|
||||||
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='shoppinglistentry',
|
|
||||||
name='created_by',
|
|
||||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='auth.user'),
|
|
||||||
preserve_default=False,
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='shoppinglistentry',
|
|
||||||
name='recipe',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cookbook.recipe'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='userpreference',
|
|
||||||
name='shopping_share',
|
|
||||||
field=models.ManyToManyField(blank=True, related_name='shopping_share', to=settings.AUTH_USER_MODEL),
|
|
||||||
),
|
|
||||||
]
|
|
@ -6,7 +6,7 @@ from django.conf import settings
|
|||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import PermissionModelMixin, ShoppingListEntry
|
from cookbook.models import ShoppingListEntry
|
||||||
|
|
||||||
|
|
||||||
def copy_values_to_sle(apps, schema_editor):
|
def copy_values_to_sle(apps, schema_editor):
|
||||||
@ -16,8 +16,10 @@ def copy_values_to_sle(apps, schema_editor):
|
|||||||
if entry.shoppinglist_set.first():
|
if entry.shoppinglist_set.first():
|
||||||
entry.created_by = entry.shoppinglist_set.first().created_by
|
entry.created_by = entry.shoppinglist_set.first().created_by
|
||||||
entry.space = entry.shoppinglist_set.first().space
|
entry.space = entry.shoppinglist_set.first().space
|
||||||
|
if entry.list_recipe:
|
||||||
|
entry.recipe = entry.list_recipe.recipe
|
||||||
if entries:
|
if entries:
|
||||||
ShoppingListEntry.objects.bulk_update(entries, ["created_by", "space", ])
|
ShoppingListEntry.objects.bulk_update(entries, ["created_by", "recipe"])
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@ -50,6 +52,11 @@ class Migration(migrations.Migration):
|
|||||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='auth.user'),
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='auth.user'),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='shoppinglistentry',
|
||||||
|
name='recipe',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cookbook.recipe'),
|
||||||
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='userpreference',
|
model_name='userpreference',
|
||||||
name='shopping_share',
|
name='shopping_share',
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
# Generated by Django 3.2.7 on 2021-10-01 22:34
|
# Generated by Django 3.2.7 on 2021-10-01 22:34
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from datetime import timedelta
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from django.utils import timezone
|
import django.db.models.deletion
|
||||||
from django.utils.timezone import utc
|
from django.utils.timezone import utc
|
||||||
from django_scopes import scopes_disabled
|
|
||||||
|
|
||||||
from cookbook.models import FoodInheritField, ShoppingListEntry
|
from django_scopes import scopes_disabled
|
||||||
|
from cookbook.models import ShoppingListEntry
|
||||||
|
|
||||||
|
|
||||||
def delete_orphaned_sle(apps, schema_editor):
|
def delete_orphaned_sle(apps, schema_editor):
|
||||||
@ -19,23 +16,6 @@ def delete_orphaned_sle(apps, schema_editor):
|
|||||||
ShoppingListEntry.objects.filter(shoppinglist=None).delete()
|
ShoppingListEntry.objects.filter(shoppinglist=None).delete()
|
||||||
|
|
||||||
|
|
||||||
def create_inheritfields(apps, schema_editor):
|
|
||||||
FoodInheritField.objects.create(name='Supermarket Category', field='supermarket_category')
|
|
||||||
FoodInheritField.objects.create(name='Ignore Shopping', field='ignore_shopping')
|
|
||||||
FoodInheritField.objects.create(name='Diet', field='diet')
|
|
||||||
FoodInheritField.objects.create(name='Substitute', field='substitute')
|
|
||||||
FoodInheritField.objects.create(name='Substitute Children', field='substitute_children')
|
|
||||||
FoodInheritField.objects.create(name='Substitute Siblings', field='substitute_siblings')
|
|
||||||
|
|
||||||
|
|
||||||
def set_completed_at(apps, schema_editor):
|
|
||||||
today_start = timezone.now().replace(hour=0, minute=0, second=0)
|
|
||||||
# arbitrary - keeping all of the closed shopping list items out of the 'recent' view
|
|
||||||
month_ago = today_start - timedelta(days=30)
|
|
||||||
with scopes_disabled():
|
|
||||||
ShoppingListEntry.objects.filter(checked=True).update(completed_at=month_ago)
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -45,6 +25,4 @@ class Migration(migrations.Migration):
|
|||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RunPython(delete_orphaned_sle),
|
migrations.RunPython(delete_orphaned_sle),
|
||||||
migrations.RunPython(create_inheritfields),
|
|
||||||
migrations.RunPython(set_completed_at),
|
|
||||||
]
|
]
|
||||||
|
@ -831,7 +831,7 @@ class ShoppingListRecipe(ExportModelOperationsMixin('shopping_list_recipe'), mod
|
|||||||
|
|
||||||
|
|
||||||
class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), models.Model, PermissionModelMixin):
|
class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), models.Model, PermissionModelMixin):
|
||||||
list_recipe = models.ForeignKey(ShoppingListRecipe, on_delete=models.CASCADE, null=True, blank=True, related_name='entries')
|
list_recipe = models.ForeignKey(ShoppingListRecipe, on_delete=models.CASCADE, null=True, blank=True) # TODO deprecate
|
||||||
food = models.ForeignKey(Food, on_delete=models.CASCADE)
|
food = models.ForeignKey(Food, on_delete=models.CASCADE)
|
||||||
unit = models.ForeignKey(Unit, on_delete=models.SET_NULL, null=True, blank=True)
|
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)
|
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE, null=True, blank=True)
|
||||||
@ -844,7 +844,7 @@ class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), model
|
|||||||
completed_at = models.DateTimeField(null=True, blank=True)
|
completed_at = models.DateTimeField(null=True, blank=True)
|
||||||
|
|
||||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||||
objects = ScopedManager(space='space')
|
objects = ScopedManager(space='shoppinglist__space')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@atomic
|
@atomic
|
||||||
|
@ -372,6 +372,15 @@ class FoodSerializer(UniqueFieldsMixin, WritableNestedModelSerializer, ExtendedR
|
|||||||
def get_shopping_status(self, obj):
|
def get_shopping_status(self, obj):
|
||||||
return ShoppingListEntry.objects.filter(space=obj.space, food=obj, checked=False).count() > 0
|
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):
|
def create(self, validated_data):
|
||||||
validated_data['name'] = validated_data['name'].strip()
|
validated_data['name'] = validated_data['name'].strip()
|
||||||
validated_data['space'] = self.context['request'].space
|
validated_data['space'] = self.context['request'].space
|
||||||
@ -670,41 +679,31 @@ class ShoppingListEntrySerializer(WritableNestedModelSerializer):
|
|||||||
|
|
||||||
def get_fields(self, *args, **kwargs):
|
def get_fields(self, *args, **kwargs):
|
||||||
fields = super().get_fields(*args, **kwargs)
|
fields = super().get_fields(*args, **kwargs)
|
||||||
|
print('shoppinglist', self.__class__, self.parent.__class__)
|
||||||
# autosync values are only needed for frequent 'checked' value updating
|
# autosync values are only needed for frequent 'checked' value updating
|
||||||
if self.context['request'] and bool(int(self.context['request'].query_params.get('autosync', False))):
|
if self.context['request'] and bool(int(self.context['request'].query_params.get('autosync', False))):
|
||||||
for f in list(set(fields) - set(['id', 'checked'])):
|
for f in list(set(fields) - set(['id', 'checked'])):
|
||||||
del fields[f]
|
del fields[f]
|
||||||
|
# extended values are computationally expensive and not needed in normal circumstances
|
||||||
|
elif not bool(int(self.context['request'].query_params.get('extended', False))) or not self.parent:
|
||||||
|
del fields['notes']
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
def run_validation(self, data):
|
|
||||||
if (
|
|
||||||
data.get('checked', False)
|
|
||||||
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()
|
|
||||||
elif not data.get('checked', False):
|
|
||||||
# if not checked set completed to None
|
|
||||||
data['completed_at'] = None
|
|
||||||
else:
|
|
||||||
# otherwise don't write anything
|
|
||||||
if 'completed_at' in data:
|
|
||||||
del data['completed_at']
|
|
||||||
|
|
||||||
return super().run_validation(data)
|
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
validated_data['space'] = self.context['request'].space
|
validated_data['space'] = self.context['request'].space
|
||||||
validated_data['created_by'] = self.context['request'].user
|
validated_data['created_by'] = self.context['request'].user
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
if validated_data['checked']:
|
||||||
|
validated_data['completed_at'] = timezone.now()
|
||||||
|
return super().update(instance, validated_data)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ShoppingListEntry
|
model = ShoppingListEntry
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'list_recipe', 'food', 'unit', 'ingredient', 'ingredient_note', 'amount', 'order', 'checked', 'recipe_mealplan',
|
'id', 'list_recipe', 'food', 'unit', 'amount', 'order', 'checked',
|
||||||
'created_by', 'created_at', 'completed_at', 'delay_until'
|
'created_by', 'created_at', 'notes', 'completed_at'
|
||||||
)
|
)
|
||||||
read_only_fields = ('id', 'created_by', 'created_at',)
|
read_only_fields = ('id', 'created_by', 'created_at',)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user