Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving json data to a Django model

I'm trying to save json data to a model. I'm getting all the data i need, how do i save them to a model?

views.py

def book_api(request):
if request.method == 'POST':
    search = request.POST['textfield']
    url = 'https://www.googleapis.com/books/v1/volumes?q=' + search
    print(url)
    r = requests.get(url).json()
    book_info = {
        'title': r['items'][0-2]['volumeInfo']['title'],
        'description': r['items'][2]['volumeInfo']['description'],
        'author_name': r['items'][0-2]['volumeInfo']['authors'],
        'genres': r['items'][0-2]['volumeInfo']['categories'],

    }
    print(book_info)

    return redirect('index')
else:
    return render(request, 'api/book_api.html')

models.py

class Genres(models.Model):
    genres = models.CharField(max_length=200)

    def __str__(self):
        return self.genres


class Authors(models.Model):
    author_name = models.CharField(max_length=200)

    def __str__(self):
        return self.author_name


class Books(models.Model):
    title = models.CharField(max_length=300)
    description = models.TextField()
    authors = models.ForeignKey(Authors, on_delete=models.CASCADE)
    genres = models.ForeignKey(Genres, on_delete=models.CASCADE)

    def __str__(self):
      return self.title

Was trying to do Books.objects.save(**book_info) but it raises a error

'Manager' object has no attribute 'save'

like image 203
Rafalpero Avatar asked Dec 17 '22 17:12

Rafalpero


1 Answers

If the answers you get from the consumption of Google's API contains different attributes in each query and you want to store them all, then you have to use a JSONField:

from django.db import models
from django.core.serializers.json import DjangoJSONEncoder
import json

class JSONField(models.TextField):
    """
    JSONField es un campo TextField que serializa/deserializa objetos JSON.
    Django snippet #1478

    Ejemplo:
        class Page(models.Model):
            data = JSONField(blank=True, null=True)

        page = Page.objects.get(pk=5)
        page.data = {'title': 'test', 'type': 3}
        page.save()
    """
    def to_python(self, value):
        if value == "":
            return None

        try:
            if isinstance(value, str):
                return json.loads(value)
        except ValueError:
            pass
        return value

    def from_db_value(self, value, *args):
        return self.to_python(value)

    def get_db_prep_save(self, value, *args, **kwargs):
        if value == "":
            return None
        if isinstance(value, dict):
            value = json.dumps(value, cls=DjangoJSONEncoder)
        return value

In your models.py:

class Book(Model.models):
    info = JSONField(null=True, blank=True)
    ...

In your views.py:

 ...
 book.info = json.loads(r.content)
 book.save()

But if you need to save always the same attributes, in your case title, description, author_name and genres:

Book.objects.create(title = r['items'][0-2]['volumeInfo']['title'], description = r['items'][2]['volumeInfo']['description'], ......)
like image 141
Jota Avatar answered Dec 27 '22 19:12

Jota