Reputation: 6888
Disclaimer: I am learning django as I apply it to a database / PHP app i inherited. The database is a bit of a mess, with no foreign key constrains, and inconsistent naming. I do not want to touch or redo anything on the database because I don't want to mes with the legacy application at all.
Stack: Python 2.7. Django 1.5, Django Rest Framework
The problem is that I have a relationship where there is an Idea that has multiple Tickers. The tickers table has the foreign key to the ideas (teaser_id) so that we have something like
**Tickers**
id teaser_id
1 1
2 1
3 1
4 2
4 2
**Ideas**
id
1
2
I had django generate the model from the database, but without the FK Constraints it didn't generate all the relationships properly. So here is haw the models are configured:
class Tickers(models.Model):
id = models.IntegerField(primary_key=True)
# I changed to this
teaser_id = models.ForeignKey(Idea)
# From
# teaser_id = models.IntegerField(null=True, blank=True)
ticker = models.CharField(max_length=135L, blank=True)
date_added = models.CharField(max_length=135L, blank=True)
class Meta:
db_table = 'teaser_tickers'
class Idea(models.Model):
id = models.IntegerField(primary_key=True)
industry_id = models.IntegerField()
post_type = models.CharField(max_length=45L)
class Meta:
db_table = 'idea'
Here are my serializers
class TickerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = myModels.Tickers
fields = (
'id'
,'teaser_id'
,'ticker'
)
class IdeaSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer(many=False, read_only=True)
ticker = TickerSerializer(many=True, read_only=True, )
teaser = myFields.TeaserField(teaser_length=200, original_field='content')
class Meta:
model = myModels.Idea
fields = (
'id'
, 'title'
, 'date_added'
, 'user'
, 'teaser'
, 'ticker'
)
I want the Ideas Resource to return the tickers as a child node set.
The REST request is for the Idea where the tickers is a child element. So I am getting an exception that ticker isn't defined in idea. Fine get that - but I am just guessing on how to set this up at this point - I am sludging through documentation and source - but was hoping someone could help me out.
THank you
Upvotes: 4
Views: 3945
Reputation: 50
As akaphenom said you have to use the related_name in your serializer, but since you don't specify any in your models you must use the default, in this case teaser_set and your IdeaSerializer
must be:
class IdeaSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer(many=False, read_only=True)
tickers = ReverseTickerSerializer(many=True, read_only=True)
teaser_set = myFields.TeaserField(teaser_length=200, original_field='content')
class Meta:
model = myModels.Idea
fields = (
'id',
'title',
'date_added',
'user',
'teaser_set',
'tickers',
)
Upvotes: 2
Reputation: 6888
SO the solution for the reverse lookup is specifying the model correctly, and namely the related_name which is the field that is created in the foreign model to perform the reverse look up. Now I specified a custom serializer to limit to the content I am interested in - but that piece is optional.
class Tickers(models.Model):
id = models.IntegerField(primary_key=True)
# I changed to this
teaser_id = models.ForeignKey(Idea, related_name='tickers')
# From
# teaser_id = models.IntegerField(null=True, blank=True)
ticker = models.CharField(max_length=135L, blank=True)
date_added = models.CharField(max_length=135L, blank=True)
class Meta:
db_table = 'teaser_tickers'
class Idea(models.Model):
id = models.IntegerField(primary_key=True)
industry_id = models.IntegerField()
post_type = models.CharField(max_length=45L)
class Meta:
db_table = 'idea'
Here are my serializers
class ReverseTickerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = myModels.Tickers
fields = (
'id'
,'ticker'
)
class IdeaSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer(many=False, read_only=True)
tickers = ReverseTickerSerializer(many=True, read_only=True)
teaser = myFields.TeaserField(teaser_length=200, original_field='content')
class Meta:
model = myModels.Idea
fields = (
'id'
, 'title'
, 'date_added'
, 'user'
, 'teaser'
, 'tickers'
)
Upvotes: 1