diff --git a/apps/recipe/migrations/0002_recipe_old_id.py b/apps/recipe/migrations/0002_recipe_old_id.py new file mode 100644 index 00000000..d5313561 --- /dev/null +++ b/apps/recipe/migrations/0002_recipe_old_id.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.7 on 2019-12-16 06:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('recipe', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='recipe', + name='old_id', + field=models.PositiveIntegerField(blank=True, default=None, null=True, verbose_name='old id'), + ), + ] diff --git a/apps/recipe/migrations/0003_recipe_slug.py b/apps/recipe/migrations/0003_recipe_slug.py new file mode 100644 index 00000000..11a5a102 --- /dev/null +++ b/apps/recipe/migrations/0003_recipe_slug.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.7 on 2019-12-16 13:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('recipe', '0002_recipe_old_id'), + ] + + operations = [ + migrations.AddField( + model_name='recipe', + name='slug', + field=models.SlugField(max_length=255, null=True, unique=True, verbose_name='Slug'), + ), + ] diff --git a/apps/recipe/models.py b/apps/recipe/models.py index 349fed7b..6eaa2155 100644 --- a/apps/recipe/models.py +++ b/apps/recipe/models.py @@ -43,22 +43,19 @@ class Recipe(TranslatedFieldsMixin, ImageMixin, BaseAttributes): STR_FIELD_NAME = 'title' - title = TJSONField(blank=True, null=True, default=None, verbose_name=_('Title'), - help_text='{"en-GB": "some text"}') + title = TJSONField(blank=True, null=True, default=None, verbose_name=_('Title'), help_text='{"en-GB": "some text"}') subtitle = TJSONField(blank=True, null=True, default=None, verbose_name=_('Subtitle'), help_text='{"en-GB": "some text"}') description = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'), help_text='{"en-GB": "some text"}') - state = models.PositiveSmallIntegerField(default=WAITING, choices=STATE_CHOICES, - verbose_name=_('State')) - author = models.CharField(max_length=255, blank=True, null=True, default=None, - verbose_name=_('Author')) - published_at = models.DateTimeField(verbose_name=_('Published at'), - blank=True, default=None, null=True, + state = models.PositiveSmallIntegerField(default=WAITING, choices=STATE_CHOICES, verbose_name=_('State')) + author = models.CharField(max_length=255, blank=True, null=True, default=None, verbose_name=_('Author')) + published_at = models.DateTimeField(verbose_name=_('Published at'), blank=True, default=None, null=True, help_text=_('Published at')) - published_scheduled_at = models.DateTimeField(verbose_name=_('Published scheduled at'), - blank=True, default=None, null=True, - help_text=_('Published scheduled at')) + published_scheduled_at = models.DateTimeField(verbose_name=_('Published scheduled at'), blank=True, default=None, + null=True, help_text=_('Published scheduled at')) + old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None) + slug = models.SlugField(unique=True, max_length=255, null=True, verbose_name=_('Slug')) objects = RecipeQuerySet.as_manager() diff --git a/apps/recipe/transfer_data.py b/apps/recipe/transfer_data.py index 4a2e97d6..22b44baa 100644 --- a/apps/recipe/transfer_data.py +++ b/apps/recipe/transfer_data.py @@ -1,19 +1,32 @@ -from django.db.models import Value, IntegerField, F from pprint import pprint + from transfer.models import PageTexts from transfer.serializers.recipe import RecipeSerializer def transfer_recipe(): - queryset = PageTexts.objects.filter(page__type="Recipe") + queryset = PageTexts.objects.filter( + page__type='Recipe', + ).values( + 'id', + 'title', + 'summary', + 'body', + 'locale', + 'state', + 'slug', + 'created_at', + 'page__attachment_suffix_url', + 'page__account_id', + ) - serialized_data = RecipeSerializer(data=list(queryset.values()), many=True) + serialized_data = RecipeSerializer(data=list(queryset), many=True) if serialized_data.is_valid(): serialized_data.save() else: - pprint(f"News serializer errors: {serialized_data.errors}") + pprint(f'Recipe serializer errors: {serialized_data.errors}') data_types = { - "recipe": [transfer_recipe] + 'recipe': [transfer_recipe] } diff --git a/apps/transfer/management/commands/transfer.py b/apps/transfer/management/commands/transfer.py index d59bacfc..b4a42349 100644 --- a/apps/transfer/management/commands/transfer.py +++ b/apps/transfer/management/commands/transfer.py @@ -13,7 +13,7 @@ class Command(BaseCommand): 'news', # перенос новостей (после №2) 'account', # №1 - перенос пользователей 'subscriber', - 'recipe', + 'recipe', # №2 - рецепты 'partner', 'establishment', # №3 - перенос заведений 'gallery', diff --git a/apps/transfer/serializers/recipe.py b/apps/transfer/serializers/recipe.py index 11698ba1..ad2d34cb 100644 --- a/apps/transfer/serializers/recipe.py +++ b/apps/transfer/serializers/recipe.py @@ -1,55 +1,87 @@ from rest_framework import serializers + +from account.models import User from recipe.models import Recipe from utils.legacy_parser import parse_legacy_news_content -class RecipeSerializer(serializers.ModelSerializer): - locale = serializers.CharField() +class RecipeSerializer(serializers.Serializer): + id = serializers.IntegerField() + title = serializers.CharField(allow_null=True) + summary = serializers.CharField(allow_null=True, allow_blank=True) body = serializers.CharField(allow_null=True) - title = serializers.CharField() - state = serializers.CharField() - created_at = serializers.DateTimeField(source="published_at", format='%m-%d-%Y %H:%M:%S') - - class Meta: - model = Recipe - fields = ( - "body", - "title", - "state", - "created_at", - 'locale', - ) + locale = serializers.CharField(allow_null=True) + state = serializers.CharField(allow_null=True) + slug = serializers.CharField(allow_null=True) + created_at = serializers.DateTimeField(format='%m-%d-%Y %H:%M:%S') + page__attachment_suffix_url = serializers.CharField(allow_null=True) + page__account_id = serializers.IntegerField(allow_null=True) def validate(self, data): - data["state"] = self.get_state(data) - data["title"] = self.get_title(data) - data["description"] = self.get_description(data) - data.pop("body") - data.pop("locale") + data.update({ + 'old_id': data.pop('id'), + 'title': self.get_title(data), + 'subtitle': self.get_subtitle(data), + 'description': self.get_description(data), + 'state': self.get_state(data), + 'created': data.pop('created_at'), + 'image': self.get_image(data), + 'created_by': self.get_account(data), + 'modified_by': self.get_account(data), + }) + + data.pop('page__account_id') + data.pop('page__attachment_suffix_url') + data.pop('summary') + data.pop('body') + data.pop('locale') return data def create(self, validated_data): - return Recipe.objects.create(**validated_data) + obj, _ = Recipe.objects.update_or_create( + old_id=validated_data['old_id'], + defaults=validated_data, + ) + return obj - def get_state(self, obj): - if obj["state"] == "published": - return Recipe.PUBLISHED - elif obj["state"] == "hidden": - return Recipe.HIDDEN - elif obj["state"] == "published_exclusive": - return Recipe.PUBLISHED_EXCLUSIVE - else: - return Recipe.WAITING + @staticmethod + def get_title(data): + if data.get('title') and data.get('locale'): + return {data['locale']: data['title']} + return None - def get_title(self, obj): - # tit = obj.get("title") - # return {"en-GB": tit} - return {obj['locale']: obj['title']} + @staticmethod + def get_subtitle(data): + if data.get('summary') and data.get('locale'): + return {data['locale']: data['summary']} + return None - def get_description(self, obj): - # desc = obj.get("body") - # return {"en-GB": desc} - content = None - if obj['body']: - content = parse_legacy_news_content(obj['body']) - return {obj['locale']: content} + @staticmethod + def get_description(data): + if data.get('body') and data.get('locale'): + content = parse_legacy_news_content(data['body']) + return {data['locale']: content} + return None + + @staticmethod + def get_state(data): + value = data.get('state') + states = { + 'published': Recipe.PUBLISHED, + 'hidden': Recipe.HIDDEN, + 'published_exclusive': Recipe.PUBLISHED_EXCLUSIVE + } + return states.get(value, Recipe.WAITING) + + @staticmethod + def get_image(data): + values = (None, 'default/missing.png') + if data.get('page__attachment_suffix_url') not in values: + return data['page__attachment_suffix_url'] + return None + + @staticmethod + def get_account(data): + if data.get('page__account_id'): + return User.objects.filter(old_id=data['page__account_id']).first() + return None