Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Mineral Catalog

Alx Ki
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Alx Ki
Python Web Development Techdegree Graduate 14,822 Points

Writing script for creating model instances from json.

I got stuck with 6th project trying to create model instances for each mineral in json.

In django docs i found info about creating classmethods for this purpose. so I did (without exception for updating just to test):

class Mineral(models.Model):
    name = models.CharField(max_length=100, unique=True)
    image_filename = models.CharField(max_length=255)
    image_caption = models.CharField(max_length=255)
    category = models.CharField(max_length=255)
    formula = models.CharField(max_length=255)
    strunz_classification = models.CharField(max_length=255)
    crystal_system = models.CharField(max_length=255)
    unit_cell = models.CharField(max_length=255)
    color = models.CharField(max_length=255)
    crystal_symmetry = models.CharField(max_length=255)
    cleavage = models.CharField(max_length=255)
    mohs_scale_hardness = models.CharField(max_length=255)
    luster = models.CharField(max_length=255)
    streak = models.CharField(max_length=255)
    diaphaneity = models.CharField(max_length=255)
    optical_properties = models.CharField(max_length=255)
    refractive_index = models.CharField(max_length=255)
    crystal_habit = models.CharField(max_length=255)
    specific_gravity = models.CharField(max_length=255)

    def __str__(self):
        return self.name

    @classmethod
    def add_minerals_to_database(cls):
        with open('minerals.json', encoding='utf8') as file:
            all_of_them = json.load(file)
            for each in all_of_them:
                Mineral(
                    name=each['name'],
                    image_filename=each['image filename'],
                    image_caption=each['image caption'],
                    category=each['category'],
                    formula=each['formula'],
                    strunz_classification=each['strunz classification'],
                    crystal_system=each['crystal system'],
                    unit_cell=each['unit cell'],
                    color=each['color'],
                    crystal_symmetry=each['crystal symmetry'],
                    cleavage=each['cleavage'],
                    mohs_scale_hardness=each['mohs scale hardness'],
                    luster=each['luster'],
                    streak=each['streak'],
                    diaphaneity=each['diaphaneity'],
                    optical_properties=each['optical properties'],
                    refractive_index=each['refractive index'],
                    crystal_habit=each['crystal habit'],
                    specific_gravity=each['specific gravity']
                ).save()

But how and where(!) to use it?? I can't just run models.py, and all I found on StackOverFlow is for old Django versions and doesn't work. Update: I'm pretty shure you know how it works, Tatiana Vasilevskaya , so if you have a minute or two, i'd appreciate that! Kenneth Love , I need your help!)

3 Answers

Kenneth Love
STAFF
Kenneth Love
Treehouse Guest Teacher

If you want to click a button to make it happen, that would require a view, wouldn't it?

If you want it to be automatic, I'd probably look at using a data migration.

Alx Ki
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Alx Ki
Python Web Development Techdegree Graduate 14,822 Points

I understand that it needs a view, Idon't understand how the script gets to db, I mean we only did it from shell. how does the script get to the manage.py shell or doesn't it need the shell?

i wrote a file:

import json

from django.core.management import settings

from minerals.models import Mineral

from Mineral_Catalog import settings as project_settings

if not settings.configured:
    settings.configure(default_settings=project_settings)


def add_minerals_to_database():
    with open('minerals\minerals.json', encoding='utf8') as file:
        all_of_them = json.load(file)
        for each in all_of_them:
            Mineral(
                name=each['name'],
                image_filename=each['image filename'],
                image_caption=each['image caption'],
                category=each['category'],
                formula=each['formula'],
                strunz_classification=each['strunz classification'],
                crystal_system=each['crystal system'],
                unit_cell=each['unit cell'],
                color=each['color'],
                crystal_symmetry=each['crystal symmetry'],
                cleavage=each['cleavage'],
                mohs_scale_hardness=each['mohs scale hardness'],
                luster=each['luster'],
                streak=each['streak'],
                diaphaneity=each['diaphaneity'],
                optical_properties=each['optical properties'],
                refractive_index=each['refractive index'],
                crystal_habit=each['crystal habit'],
                specific_gravity=each['specific gravity']
            ).save()

add_minerals_to_database()

(Found thing about settings on stackoverflow, don't really know if it's right)

It doesn't work, because, i guess, db is not initialized or smth.

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

It would be a view just like all of the other views you've created. Something along the lines of:

def import_minerals(request):
    ...
    for mineral in all_of_them:
        Mineral.objects.create(...)

The first ... is your existing bit where you load the minerals from the JSON file. The second is where you fill in the details of the mineral.

Alx Ki
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Alx Ki
Python Web Development Techdegree Graduate 14,822 Points

Thank you, Kenneth Love. Somewhy it took me long to understand how to access a db with django after flask and peewee..

Now db updates automatically each time you access main page! (What if new minerals appear!)

If you run python manage.py shell from the directory with your manage.py file that will launch a shell. From that shell you can from <app-name>.models import Mineral. Then you can call the method.

Tatiana Vasilevskaya
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Tatiana Vasilevskaya
Python Web Development Techdegree Graduate 28,600 Points

As far as I remember the task explicitly asks to write a script that populates a database from json data, which could be a migration as Kenneth suggested or a separate script that reads a json file, creates Mineral instances and saves into the database. If you want, you can check my script.

Alx Ki
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Alx Ki
Python Web Development Techdegree Graduate 14,822 Points

Now trying to build a separate script. Thank you! I'll surely take a look at your script but only after mine is done)) Just want to make it myself.