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:
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...