Home > Net >  meal, created = Meal.objects.get_or_create(name=meal_data.get('name', '')) Attri
meal, created = Meal.objects.get_or_create(name=meal_data.get('name', '')) Attri

Time:01-31

this is django rest_framework api I created this api for restourant. This is menu api . I want to save menu.json's data to my database, but I could not. Can you give any advice to save json data to my models. I got this error:

      File "C:\Users\OSMAN MERT\Desktop\menu\menu_core\api\models.py", line 36, in store_json_data
        meal, created = Meal.objects.get_or_create(name=meal_data.get('name', ''))
    AttributeError: 'str' object has no attribute 'get'

How can I solve it? I need your help?

models.py

    from django.db import models
    import json
    # Create your models here.
    
    class Meal(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=100)
        is_vegetarian = models.BooleanField(default=False)
        is_vegan = models.BooleanField(default=False)
    
    class Ingredient(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=100)
        groups = models.CharField(max_length=100)
    
    class Option(models.Model):
        id = models.AutoField(primary_key=True)
        ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
        name = models.CharField(max_length=100)
        quality = models.CharField(max_length=100)
        price = models.FloatField()
        per_amount = models.CharField(max_length=100)
    
    class MealIngredient(models.Model):
        id = models.AutoField(primary_key=True)
        meal = models.ForeignKey(Meal, on_delete=models.CASCADE)
        ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
    
    
    
    
    path = r"C:\Users\OSMAN MERT\Desktop\menu\menu_core\menu.json"
    
    def store_json_data(json_data):
        for meal_data in json_data:
            meal, created = Meal.objects.get_or_create(name=meal_data.get('name', ''))
            if not created:
                meal.is_vegetarian = meal_data.get('is_vegetarian', False)
                meal.is_vegan = meal_data.get('is_vegan', False)
                meal.save()
            for ingredient_data in meal_data.get('ingredients', []):
                ingredient, _ = Ingredient.objects.get_or_create(name=ingredient_data.get('name', ''), meal=meal)
                for option_data in ingredient_data.get('options', []):
                    option, _ = Option.objects.get_or_create(quality=option_data.get('quality', ''), ingredient=ingredient)
                    option.price = option_data.get('price', 0)
                    option.save()
    
    def load_json_file(path):
        with open(path) as json_file:
            json_data = json.load(json_file)
            store_json_data(json_data)
    
    load_json_file(path)

This is some data from menu.json not all code include there. menu.json

    {
    "meals": [
      {
        "id": 1,
        "name": "Rice and chicken bowl",
        "ingredients": [
          { "name": "Rice", "quantity": 120, "quantity_type": "gram" },
          { "name": "Chicken", "quantity": 85, "quantity_type": "gram" }
        ]
      },
      {
        "id": 2,
        "name": "Pasta with marinara sauce and vegetables",
        "ingredients": [
          { "name": "Pasta", "quantity": 115, "quantity_type": "gram" },
          {
            "name": "Marinara sauce",
            "quantity": 120,
            "quantity_type": "millilitre"
          },
          { "name": "Vegetables", "quantity": 240, "quantity_type": "gram" }
        ]
      },
      {
        "id": 3,
        "name": "Grilled chicken with roasted vegetables",
        "ingredients": [
          { "name": "Chicken", "quantity": 85, "quantity_type": "gram" },
          { "name": "Vegetables", "quantity": 240, "quantity_type": "gram" }
        ]
      },
      {
        "id": 4,
        "name": "Beef stir-fry with rice",
        "ingredients": [
          { "name": "Beef", "quantity": 115, "quantity_type": "gram" },
          { "name": "Rice", "quantity": 120, "quantity_type": "gram" },
          { "name": "Vegetables", "quantity": 240, "quantity_type": "gram" }
        ]
      },
      {
        "id": 5,
        "name": "Pork chops with mashed potatoes and gravy",
        "ingredients": [
          { "name": "Pork chops", "quantity": 115, "quantity_type": "gram" },
          {
            "name": "Mashed potatoes",
            "quantity": 120,
            "quantity_type": "gram"
          },
          { "name": "Gravy", "quantity": 120, "quantity_type": "millilitre" }
        ]
      },
      {
        "id": 6,
        "name": "Grilled salmon with roasted asparagus",
        "ingredients": [
          { "name": "Salmon", "quantity": 85, "quantity_type": "gram" },
          { "name": "Asparagus", "quantity": 240, "quantity_type": "gram" }
        ]
      },
      {
        "id": 7,
        "name": "Shrimp scampi with linguine",
        "ingredients": [
          { "name": "Shrimp", "quantity": 115, "quantity_type": "gram" },
          { "name": "Linguine", "quantity": 115, "quantity_type": "gram" },
          { "name": "Butter", "quantity": 10, "quantity_type": "millilitre" },
          { "name": "Garlic", "quantity": 10, "quantity_type": "gram" },
          { "name": "White wine", "quantity": 60, "quantity_type": "millilitre" }
        ]
      },
      {
        "id": 8,
        "name": "Vegetarian stir-fry with tofu",
        "ingredients": [
          { "name": "Tofu", "quantity": 115, "quantity_type": "gram" },
          { "name": "Rice", "quantity": 120, "quantity_type": "gram" },
          { "name": "Vegetables", "quantity": 240, "quantity_type": "gram" }
        ]
      },
      {
        "id": 9,
        "name": "Fruit salad with mixed berries and yogurt",
        "ingredients": [
          { "name": "Mixed berries", "quantity": 240, "quantity_type": "gram" },
          { "name": "Yogurt", "quantity": 120, "quantity_type": "millilitre" }
        ]
      }
    ],
  
    "ingredients": [
      {
        "name": "Rice",
        "groups": ["vegan", "vegetarian"],
        "options": [
          {
            "name": "Long grain white rice",
            "quality": "high",
            "price": 3,
            "per_amount": "kilogram"
          },
          {
            "name": "Medium grain brown rice",
            "quality": "medium",
            "price": 2,
            "per_amount": "kilogram"
          },
          {
            "name": "Quick cooking white rice",
            "quality": "low",
            "price": 1.5,
            "per_amount": "kilogram"
          }
        ]
      }


CodePudding user response:

first, your menu.json you upload incorrect format. Missing some character.

Assum you have correct json like you upload to variable json_data

Error you show mean meal_data you get is string. And it can not use attribute get.

Try update like this for correct get every meal in json. meal_data become dict and can use get

    for meal_data in json_data.get("meals"):
        meal, created = Meal.objects.get_or_create(name=meal_data.get('name', ''))

CodePudding user response:

The main thing is that you are not looping correctly through the dictionary. You can either:

def store_json_data(json_data):
    for key, meal_data in json_data.items():
        if key == 'meals':
            for meal in meal_data:
                ...

        if key == 'ingredients':
            for ingredient in meal_data:
                ...

Or, instead of looping through the dictionary key : pair, access the list value manually and then loop through it:

def store_json_data(json_data):
    meals = json_data.get("meals")
    ingredients = json_data["ingredients"]

    for meal in meals:
        ...

    for ingredient in ingredients:
        ...

That being said, what you are trying to do will not work, since when you makemigrations for the first time, database tables are not yet created and will raise an OperationalError.

I would suggest using post_migrate signal to populate your tables.

  • Related