fixed import export
This commit is contained in:
parent
38e5882376
commit
577af85d38
@ -42,7 +42,7 @@ class UserPreferenceSerializer(serializers.ModelSerializer):
|
||||
class StorageSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Storage
|
||||
fields = ('name', 'method', 'username', 'created_by')
|
||||
fields = ('id', 'name', 'method', 'username', 'created_by')
|
||||
|
||||
|
||||
class SyncSerializer(serializers.ModelSerializer):
|
||||
@ -58,9 +58,16 @@ class SyncLogSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class KeywordSerializer(UniqueFieldsMixin, serializers.ModelSerializer):
|
||||
def create(self, validated_data):
|
||||
# since multi select tags dont have id's duplicate names might be routed to create
|
||||
obj, created = Keyword.objects.get_or_create(**validated_data)
|
||||
return obj
|
||||
|
||||
class Meta:
|
||||
model = Keyword
|
||||
fields = '__all__'
|
||||
fields = ('id', 'name', 'icon', 'description', 'created_by', 'created_at', 'updated_at')
|
||||
|
||||
read_only_fields = ('id',)
|
||||
|
||||
|
||||
class UnitSerializer(UniqueFieldsMixin, serializers.ModelSerializer):
|
||||
|
@ -314,7 +314,9 @@
|
||||
addIngredient: function (step) { //TODO see if default can be generated from options request
|
||||
step.ingredients.push({
|
||||
'food': undefined,
|
||||
'unit': undefined,
|
||||
'unit': {
|
||||
'name': '{{request.user.userpreference.default_unit}}'
|
||||
},
|
||||
'amount': 0,
|
||||
'note': '',
|
||||
'order': 0,
|
||||
@ -355,10 +357,13 @@
|
||||
this.units_loading = true
|
||||
this.$http.get("{% url 'api:unit-list' %}" + '?query=' + query + '&limit=10').then((response) => {
|
||||
this.units = response.data;
|
||||
for (let s of this.recipe.steps){
|
||||
for (let i of s.ingredients) {
|
||||
if (i.unit.id === undefined) {
|
||||
this.units.push(i.unit)
|
||||
|
||||
if (this.recipe !== undefined) {
|
||||
for (let s of this.recipe.steps) {
|
||||
for (let i of s.ingredients) {
|
||||
if (i.unit.id === undefined) {
|
||||
this.units.push(i.unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -372,10 +377,12 @@
|
||||
this.$http.get("{% url 'api:food-list' %}" + '?query=' + query + '&limit=10').then((response) => {
|
||||
this.foods = response.data
|
||||
|
||||
for (let s of this.recipe.steps){
|
||||
for (let i of s.ingredients) {
|
||||
if (i.food.id === undefined) {
|
||||
this.foods.push(i.food)
|
||||
if (this.recipe !== undefined) {
|
||||
for (let s of this.recipe.steps) {
|
||||
for (let i of s.ingredients) {
|
||||
if (i.food.id === undefined) {
|
||||
this.foods.push(i.food)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,20 @@
|
||||
import base64
|
||||
import json
|
||||
import re
|
||||
from json import JSONDecodeError
|
||||
|
||||
from django.contrib import messages
|
||||
from django.core.files.base import ContentFile
|
||||
from django.db import IntegrityError
|
||||
from django.http import HttpResponseRedirect, JsonResponse, HttpResponse
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework.renderers import JSONRenderer
|
||||
|
||||
from cookbook.forms import ExportForm, ImportForm
|
||||
from cookbook.helper.permission_helper import group_required
|
||||
from cookbook.models import Ingredient, Recipe, Unit, Food, Keyword, Food
|
||||
from cookbook.models import Recipe
|
||||
from cookbook.serializer import RecipeSerializer
|
||||
|
||||
|
||||
@group_required('user')
|
||||
@ -20,44 +22,28 @@ def import_recipe(request):
|
||||
if request.method == "POST":
|
||||
form = ImportForm(request.POST)
|
||||
if form.is_valid():
|
||||
data = json.loads(form.cleaned_data['recipe'])
|
||||
try:
|
||||
data = json.loads(form.cleaned_data['recipe'])
|
||||
|
||||
recipe = Recipe.objects.create(name=data['recipe']['name'], instructions=data['recipe']['instructions'],
|
||||
working_time=data['recipe']['working_time'], waiting_time=data['recipe']['waiting_time'],
|
||||
created_by=request.user, internal=True)
|
||||
sr = RecipeSerializer(data=data)
|
||||
if sr.is_valid():
|
||||
sr.validated_data['created_by'] = request.user
|
||||
recipe = sr.save()
|
||||
|
||||
for k in data['keywords']:
|
||||
try:
|
||||
Keyword.objects.create(name=k['name'], icon=k['icon'], description=k['description']).save()
|
||||
except IntegrityError:
|
||||
pass
|
||||
if data['image']:
|
||||
fmt, img = data['image'].split(';base64,')
|
||||
ext = fmt.split('/')[-1]
|
||||
recipe.image = ContentFile(base64.b64decode(img), name=f'{recipe.pk}.{ext}') # TODO possible security risk, maybe some checks needed
|
||||
recipe.save()
|
||||
|
||||
recipe.keywords.add(Keyword.objects.get(name=k['name']))
|
||||
messages.add_message(request, messages.SUCCESS, _('Recipe imported successfully!'))
|
||||
return HttpResponseRedirect(reverse_lazy('view_recipe', args=[recipe.pk]))
|
||||
else:
|
||||
messages.add_message(request, messages.ERROR, _('Something went wrong during the import!'))
|
||||
messages.add_message(request, messages.WARNING, sr.errors)
|
||||
except JSONDecodeError:
|
||||
messages.add_message(request, messages.ERROR, _('Could not parse the supplied JSON!'))
|
||||
|
||||
for u in data['units']:
|
||||
try:
|
||||
Unit.objects.create(name=u['name'], description=u['description']).save()
|
||||
except IntegrityError:
|
||||
pass
|
||||
|
||||
for i in data['ingredients']:
|
||||
try:
|
||||
Food.objects.create(name=i['name']).save()
|
||||
except IntegrityError:
|
||||
pass
|
||||
|
||||
for ri in data['recipe_ingredients']:
|
||||
Ingredient.objects.create(recipe=recipe, ingredient=Food.objects.get(name=ri['food']),
|
||||
unit=Unit.objects.get(name=ri['unit']), amount=ri['amount'], note=ri['note'])
|
||||
|
||||
if data['image']:
|
||||
fmt, img = data['image'].split(';base64,')
|
||||
ext = fmt.split('/')[-1]
|
||||
recipe.image = ContentFile(base64.b64decode(img), name=f'{recipe.pk}.{ext}')
|
||||
recipe.save()
|
||||
|
||||
messages.add_message(request, messages.SUCCESS, _('Recipe imported successfully!'))
|
||||
return HttpResponseRedirect(reverse_lazy('view_recipe', args=[recipe.pk]))
|
||||
else:
|
||||
form = ImportForm()
|
||||
|
||||
@ -72,36 +58,20 @@ def export_recipe(request):
|
||||
if form.is_valid():
|
||||
recipe = form.cleaned_data['recipe']
|
||||
if recipe.internal:
|
||||
export = {
|
||||
'recipe': {'name': recipe.name, 'instructions': recipe.instructions, 'working_time': recipe.working_time, 'waiting_time': recipe.working_time},
|
||||
'units': [],
|
||||
'ingredients': [],
|
||||
'recipe_ingredients': [],
|
||||
'keywords': [],
|
||||
'image': None
|
||||
}
|
||||
|
||||
for k in recipe.keywords.all():
|
||||
export['keywords'].append({'name': k.name, 'icon': k.icon, 'description': k.description})
|
||||
|
||||
for ri in Ingredient.objects.filter(recipe=recipe).all():
|
||||
if ri.unit not in export['units']:
|
||||
export['units'].append({'name': ri.unit.name, 'description': ri.unit.description})
|
||||
if ri.ingredient not in export['ingredients']:
|
||||
export['ingredients'].append({'name': ri.ingredient.name})
|
||||
|
||||
export['recipe_ingredients'].append({'food': ri.ingredient.name, 'unit': ri.unit.name, 'amount': float(ri.amount), 'note': ri.note})
|
||||
export = RecipeSerializer(recipe).data
|
||||
|
||||
if recipe.image and form.cleaned_data['image']:
|
||||
with open(recipe.image.path, 'rb') as img_f:
|
||||
export['image'] = f'data:image/png;base64,{base64.b64encode(img_f.read()).decode("utf-8")}'
|
||||
|
||||
json_string = JSONRenderer().render(export).decode("utf-8")
|
||||
|
||||
if form.cleaned_data['download']:
|
||||
response = HttpResponse(json.dumps(export), content_type='text/plain')
|
||||
response = HttpResponse(json_string, content_type='text/plain')
|
||||
response['Content-Disposition'] = f'attachment; filename={recipe.name}.json'
|
||||
return response
|
||||
|
||||
context['export'] = json.dumps(export, indent=4)
|
||||
context['export'] = re.sub(r'"id":([0-9])+,', '', json_string)
|
||||
else:
|
||||
form.add_error('recipe', _('External recipes cannot be exported, please share the file directly or select an internal recipe.'))
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user