RubyNoob
RubyNoob

Reputation: 547

ModelForm displays ForeignKey table values, not choices

I'm creating a Django app where each site has a single category, selected from a range of possible categories. So I have two models: Site, and Category.

I want a many-to-one relationship between the Site and Category models. The Category table contains a selection of different categories, and each Site record will have a foreign key referencing one of those categories.

models.py:

from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible # for python 2 support

class Site(models.Model):
    Category = models.ForeignKey('Category')

    def __str__(self):
    return self.Name

CATEGORY_CHOICES = (
                    ('AU', 'Automobiles'),
                    ('BE', 'Beauty Products'),
                    ('GR', 'Groceries'),
                    )

class Category(models.Model):
    Category = models.CharField(choices=CATEGORY_CHOICES,max_length=2)

    def __str__(self):
    return '%s' % (self.Category)

forms.py:

from django.forms import ModelForm
from sites.models import Site

class NewSiteForm(ModelForm):
    class Meta:
        model = Site
        fields = ['Category']

newsite.html:

<!DOCTYPE html>
<form method="post" action="">
{{ form}}
</form>

Newsite.html gives me a Category dropdown that lists values already stored in my Category database, rather than listing the contents of the choices tuples defined in the Category model. so I'm getting this:

<!DOCTYPE html>
<form method="post" action="">
<tr><th><label for="id_Category">Category:</label></th><td><select                 id="id_Category" name="Category">
<option value="" selected="selected">---------</option>
<option value="1">AU</option>
<option value="2">BA</option>
<option value="3">BE</option>
<option value="4">BO</option>
<option value="5">PH</option>
<option value="6">CO</option>
<option value="7">CC</option>
<option value="8">CB</option>
<option value="9">CE</option>
<option value="10">CS</option>
<option value="11">CA</option>
<option value="12">EA</option>
<option value="13">EC</option>
<option value="14">FA</option>
<option value="15">GR</option>
<option value="16">HA</option>
<option value="17">HE</option>
<option value="18">HG</option>
<option value="19">IN</option>
<option value="20">JE</option>
<option value="21">LT</option>
<option value="22">MS</option>
<option value="23">MU</option>
<option value="24">MI</option>
<option value="25">OF</option>
<option value="26">OU</option>
<option value="27">PC</option>
<option value="28">SH</option>
<option value="29">SO</option>
<option value="30">SP</option>
<option value="31">TO</option>
<option value="32">TY</option>
<option value="33">DV</option>
<option value="34">CL</option>
<option value="35">WA</option>
<option value="36">WI</option>
</select></td></tr>
</form>

I want the form to just display the three choices defined in the model, rather than the contents of the database, like this:

<!DOCTYPE html>
<form method="post" action="">
<tr><th><label for="id_Category">Category:</label></th><td><select                 id="id_Category" name="Category">
<option value="" selected="selected">---------</option>
<option value="AU">Auto</option>
<option value="BE">Beauty Products</option>
<option value="GR">Groceries</option>
</select></td></tr>
</form>

What am I not understanding here and how do I make this work?

(Note that there will be a tuple in CATEGORY_CHOICES giving a readable choice for every two-letter entry stored in the Category table, but I am saving space by not listing all of them in this question).

Upvotes: 1

Views: 243

Answers (2)

RubyNoob
RubyNoob

Reputation: 547

My model structure was bad. It didn't make sense to have separate choices for the Category model. What I should have done was:

1) Either just deleted the Category model altogether and used the CATEGORY_CHOICES directly for the Category field in the Site model, abandoning the idea of a foreign key.

2) Transferred the human-readable values that I was storing in CATEGORY_CHOICES into the database values for the Category model. and deleted the CATEGORY_CHOICES. I eventually opted for this, as there will be other fields associated with Category, like 'Approved'. So it still makes sense to have a separate 'Category' model.

Upvotes: 0

falsetru
falsetru

Reputation: 368914

You need to specify Category model:

class NewSiteForm(ModelForm):
    class Meta:
        model = Category # <--
        fields = ['Category']

Upvotes: 1

Related Questions