Как сделать так, чтобы функция DRF Serializer create () создавала только те записи, которые еще не существуют? - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть две таблицы, которые связаны между собой через кросс-таблицу. (Рецепты <-> Ингредиенты) Мой сериализатор работает нормально, я могу отправлять POST-запросы, и он сохраняет все. Проблема заключается в том, что каждый раз, когда приходит новый Рецепт, скажем, просто скажем, Ингредиент «Молоко», мой Serializer создает новую запись в моей базе данных под названием «Молоко», хотя у меня уже есть запись «Молоко» в моей базе данных. Как мне сказать моему сериализатору использовать идентификатор уже существующей записи вместо того, чтобы каждый раз создавать новую для кросс-таблицы.

Вот как я думал, что могу это исправить, но это явно не помогает :

class RecipeIngredientSerializer(serializers.ModelSerializer):

    ingredient = IngerdientSerializer()

    class Meta:
        model = recipe_ingredients
        fields = ['amount', 'unit', 'ingredient']

    def create(self, validated_data):
        ingredient_validated_data = validated_data.pop('ingredient')
        ingredient_serializer = self.fields['ingredient']

        ingredientDict = dict(ingredient_validated_data)

// This is where I try to check if there is already an ingredient with the name from the form
        ingredientObj = ingredient.objects.all().filter(ingredient_name=ingredientDict['ingredient_name']).
        if not ingredientObj:
            ingredient_instance = ingredient.objects.create(**ingredientDict)
            validated_data['ingredient'] = ingredient_instance
        else:
            ingredient_instance = ingredient_serializer.create(ingredientDict)
            validated_data['ingredient'] = ingredient_instance           

        recipe_ingredients_instance = recipe_ingredients.objects.create(**validated_data)
        return recipe_ingredients_instance

Этот код также, кажется, работает, по крайней мере, я нахожу существующий ингредиент, но после последнего create () кажется, что он игнорирует все, что я помещаю sh в объект validated_data['ingredient'].

РЕДАКТИРОВАТЬ мои модели:

class recipe_ingredients(models.Model):
    recipe = models.ForeignKey(recipe, models.CASCADE)
    ingredient = models.ForeignKey(ingredient, models.CASCADE)
    amount = models.IntegerField(default=0)
    unit = models.CharField(max_length=50)

    def __str__(self):
        return self.ingredient.ingredient_name + ' of Recipe: ' + self.recipe.recipe_name

class recipe(models.Model):
    recipe_name = models.CharField(max_length=200)
    assembly_time = models.IntegerField(default=0)
    number_of_servings = models.IntegerField(default=0)
    tags = models.ManyToManyField(tag, blank=True)

    def __str__(self):
        return self.recipe_name

class ingredient(models.Model):
    ingredient_name = models.CharField(max_length=200)
    ingredient_calories = models.IntegerField('Calories per 100 Units', default=-1)
    default_unit = models.CharField(max_length=50)

    def __str__(self):
        return self.ingredient_name

1 Ответ

0 голосов
/ 12 февраля 2020

Я получил ответ, наконец. Моя ошибка в этой строке в моем сериализаторе:

ingredientObj = ingredient.objects.all().filter(ingredient_name=ingredientDict['ingredient_name']).
    if not ingredientObj:
        ingredient_instance = ingredient.objects.create(**ingredientDict)
        validated_data['ingredient'] = ingredient_instance

Я изменил ее сейчас, чтобы она выглядела примерно так:

ingredientObj = ingredient.objects.all().filter(ingredient_name=ingredientDict['ingredient_name']).
    if len(ingredientObj):
        ingredient_instance = ingredientObj.first()
        validated_data['ingredient'] = ingredient_instance

ingredient.object.create(**ingredientDict) действительно создает новый объект ( кто бы знал;)). Это, вероятно, все еще уродливое решение, и я открыт для большей критики, но пока это работает.

...