Skip to content
Advertisement

Tango with Django (v1.9/1.10) – Chapter 5, populate_rango issues

I will try to be concise. The background for this issue is that I’m familiar with Python, however I am BRAND NEW to django. This book is my first exposure to it and I’ve come to find the more I work through the book that online Q/A’s for django are not very general, thus making it harder to “just google it” and find an answer.

    MY ENVIRONMENT

Resource: Tango with Django (for version 1.9/1.10)
Distro: Elementary OS, Patched to the latest
Python Version: 3.5
Django Version: 1.11.x

    MY PROBLEM

What Is my Error: django.core.exceptions.FieldError
What are the Details: Invalid field name(s) for model Page: ‘category’.
What does the Error mean?: Per The Docs, This error is raised when there is a problem with a field inside a model..Of the reasons listed The following look relevant to my issue:

  • An infinite loop is caused by ordering.
  • I have verified the the order in which the fields are declared in the model is consistent with how the add_page. as well, I have debugged my code and see that all the fields appear to be correct as they pass through the various functions. however I’m thinking perhaps [this] is might be the issue. I think the work ‘category’ is somehow referencing the category class? total troubleshooting conjecture.
  • A Feild name is invalid
  • It’s always something simple, I’ve checked this out and the naming and usage of variables is consistent throughout the code. I’ve also double checked my code against the book. Everything seems in order, the code just isn’t working.

    The Traceback

    Traceback (most recent call last):
      File "/home/dj/opt/pycharm-2017.2.3/helpers/pydev/pydevd.py", line 1599, in <module>
        globals = debugger.run(setup['file'], None, None, is_module)
      File "/home/dj/opt/pycharm-2017.2.3/helpers/pydev/pydevd.py", line 1026, in run
        pydev_imports.execfile(file, globals, locals)  # execute the script
      File "/home/dj/opt/pycharm-2017.2.3/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
        exec(compile(contents+"n", file, 'exec'), glob, loc)
      File "/home/dj/Code/tango-with-django-book/workspace/tango_with_django_project/populate_rango.py", line 83, in <module>
        populate()
      File "/home/dj/Code/tango-with-django-book/workspace/tango_with_django_project/populate_rango.py", line 59, in populate
        add_page(c, p["title"], p["url"])
      File "/home/dj/Code/tango-with-django-book/workspace/tango_with_django_project/populate_rango.py", line 68, in add_page
        p = Page.objects.get_or_create(category=cat, title=title)[0]
      File "/usr/local/lib/python3.5/dist-packages/django/db/models/manager.py", line 85, in manager_method
        return getattr(self.get_queryset(), name)(*args, **kwargs)
      File "/usr/local/lib/python3.5/dist-packages/django/db/models/query.py", line 459, in get_or_create
        lookup, params = self._extract_model_params(defaults, **kwargs)
      File "/usr/local/lib/python3.5/dist-packages/django/db/models/query.py", line 534, in _extract_model_params
        "', '".join(sorted(invalid_params)),
    django.core.exceptions.FieldError: Invalid field name(s) for model Page: 'category'.
    

    populate_rango.py

    import os
    
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tango_with_django_project.settings')
    
    import django
    django.setup() #imports Django projects settings into the context of this script
    
    from rango.models import Category, Page
    
    def populate():
        # First, we will create lists of dictionaries containing the pages we want to add
        # into each category.
        # Then, we will create a dictionary of dictionaries for our categories. 
        # This might seem a little bit confusing, but it allows us to iterate through each data structure, 
        # and add the data to our models. 
    
    
        # List of Dictionaries of "Python" Category pages... Tile:value, URL:value
        python_pages = [
            {"title": "Official Python Tutorial", "url": "https://docs.python.org/2/tutorial/"},
            {"title": "How to think like a Computer Scientist" ,"url": "http://www.greenteapress.com/thinkpython/"},
            {"title": "Learn python in Ten Minutes" ,"url": "https://www.korokithakis.net/tutorials"}
        ]
    
        # List of Dictionaries of "django" Category pages... Title:value, URL:value
        django_pages = [
            {"title":"Official Django Tutorial" ,"url":"https://docs.djangoprojects.com/en/1.11/intro/tutorial01/"},
            {"title":"Django Rocks" ,"url":"https://www.djangorocks.com"},
            {"title":"How to Tango with Django" ,"url":"https://tangowithdjango.com/"}
        ]
    
        # List of Dictionaries of "Other" Category pages... Title:value, URL:value
        other_pages = [
            {"title":"Bottle" ,"url":"http://bottlepy.org/docs/dev/"},
            {"title":"Flask" ,"url":"http://flask.pocoo.org/"}
    
        ]
    
        # A Dictionary of Categories. Passing the pages defined above to the "pages" attribute (making a page) and then applything the tag to which their definied
        # category. 
        cats = {
            "Python": {"pages": python_pages},
            "Django": {"pages": django_pages},
            "Other Frameworks": {"pages": other_pages}
        }
    
        # If you want to add more categories or pages, add them to the 
        # dictionaies above. 
    
        # The code below goes through the cats directory, then adds each category. 
            # and then adds all the associated pages for that category.
            # if you are using python 2.x then use cat.iteritems() see
            # https://docs.quantifiedcode.com/python-anti-patterns/readability
            # for more information about how to iterate over a dictionary properly
    
        for cat, cat_data in cats.items():
            c = add_cat(cat)
            for p in cat_data["pages"]:
                add_page(c, p["title"], p["url"])
    
        # Print out the categories we have added.    
        for c in Category.objects.all():
            for p in Page.objects.filter(category=c):
                print("- {0} - {1}".format(str(c), str(p)))
    
    
    def add_page(cat, title, url, views=0):
        p = Page.objects.get_or_create(category=cat, title=title)[0]
        p.url = url
        p.views = views
        p.save()
        return p
    
    
    def add_cat(name):
        c = Category.objects.get_or_create(name=name)[0]
        c.save()
        return c
    
    
    if __name__ == '__main__':
        print("Starting Rango Population script...")
        populate()
    

    models.py

    from django.db import models
    
    
    # Create your models here.
    class Category(models.Model):
        name = models.CharField(max_length=128, unique=True)
    
        class Meta:
            verbose_name_plural = 'Categories'
    
        def __str__(self):
            return self.name
    
    
    class Page(models.Model):
        Category = models.ForeignKey(Category)
        title = models.CharField(max_length=128)
        url = models.URLField()
        views = models.IntegerField(default=0)
    
    
        def __str__(self):
            return self.title
    

    for what it’s worth, this issue persists even if I rebuild the database. (rm app.db, makemigrations, migrate)

    Advertisement

    Answer

    class Page(models.Model):
        Category = models.ForeignKey(Category)
    

    Variable names are case sensitive – this includes field names and other class attributes. Change Category = models.ForeignKey(Category) to category = models.ForeignKey(Category) to fit model coding style then rebuild your db tables and you should be ok to do Page.objects.get_or_create(category=cat...

    User contributions licensed under: CC BY-SA
    6 People found this is helpful
    Advertisement