- Notifications
You must be signed in to change notification settings - Fork 300
Support polymorphic models#211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dd4d4ec
8c73d95
681b5aa
96cbab0
5c63425
fddb06b
22829d1
d565334
e840438
19b0238
0ddf5ca
b8bf612
8fd4617
275793c
a26df13
2278976
8563b65
4aaeac2
030f6c8
ca23885
ae759e5
37c5ae6
f36821b
4eec4aa
bc12e0f
6b4f45b
36f3b6a
05cdb51
c1afe35
8ff5465
35c90d4
c5599c0
8d94efb
89ad607
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -34,6 +34,8 @@ pip-delete-this-directory.txt | ||
# Tox | ||
.tox/ | ||
.cache/ | ||
.python-version | ||
# VirtualEnv | ||
.venv/ | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
Adam Wróbel <https://adamwrobel.com> | ||
Christian Zosel <https://zosel.ch> | ||
Greg Aker <greg@gregaker.net> | ||
Jamie Bliss <astronouth7303@gmail.com> | ||
Jerel Unruh <mail@unruhdesigns.com> | ||
Léo S. <leo@naeka.fr> | ||
Matt Layman <http://www.mattlayman.com> | ||
Oliver Sauder <os@esite.ch> | ||
Yaniv Peer <yanivpeer@gmail.com> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.11.1 on 2017-05-17 14:49 | ||
from __future__ import unicode_literals | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
class Migration(migrations.Migration): | ||
dependencies = [ | ||
('contenttypes', '0002_remove_content_type_name'), | ||
('example', '0002_taggeditem'), | ||
] | ||
operations = [ | ||
migrations.CreateModel( | ||
name='Company', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('name', models.CharField(max_length=100)), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='Project', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('topic', models.CharField(max_length=30)), | ||
], | ||
options={ | ||
'abstract': False, | ||
}, | ||
), | ||
migrations.AlterField( | ||
model_name='comment', | ||
name='entry', | ||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='example.Entry'), | ||
), | ||
migrations.CreateModel( | ||
name='ArtProject', | ||
fields=[ | ||
('project_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='example.Project')), | ||
('artist', models.CharField(max_length=30)), | ||
], | ||
options={ | ||
'abstract': False, | ||
}, | ||
bases=('example.project',), | ||
), | ||
migrations.CreateModel( | ||
name='ResearchProject', | ||
fields=[ | ||
('project_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='example.Project')), | ||
('supervisor', models.CharField(max_length=30)), | ||
], | ||
options={ | ||
'abstract': False, | ||
}, | ||
bases=('example.project',), | ||
), | ||
migrations.AddField( | ||
model_name='project', | ||
name='polymorphic_ctype', | ||
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_example.project_set+', to='contenttypes.ContentType'), | ||
), | ||
migrations.AddField( | ||
model_name='company', | ||
name='current_project', | ||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='companies', to='example.Project'), | ||
), | ||
migrations.AddField( | ||
model_name='company', | ||
name='future_projects', | ||
field=models.ManyToManyField(to='example.Project'), | ||
), | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -6,6 +6,7 @@ | ||
from django.contrib.contenttypes.fields import GenericRelation | ||
from django.db import models | ||
from django.utils.encoding import python_2_unicode_compatible | ||
from polymorphic.models import PolymorphicModel | ||
class BaseModel(models.Model): | ||
@@ -86,3 +87,25 @@ class Comment(BaseModel): | ||
def __str__(self): | ||
return self.body | ||
class Project(PolymorphicModel): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice use of the | ||
topic = models.CharField(max_length=30) | ||
class ArtProject(Project): | ||
artist = models.CharField(max_length=30) | ||
class ResearchProject(Project): | ||
supervisor = models.CharField(max_length=30) | ||
@python_2_unicode_compatible | ||
class Company(models.Model): | ||
name = models.CharField(max_length=100) | ||
current_project = models.ForeignKey(Project, related_name='companies') | ||
future_projects = models.ManyToManyField(Project) | ||
def __str__(self): | ||
return self.name |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,12 @@ | ||
from datetime import datetime | ||
import rest_framework | ||
from rest_framework_json_api import serializers, relations | ||
from example.models import Blog, Entry, Author, AuthorBio, Comment, TaggedItem | ||
from packaging import version | ||
from example.models import ( | ||
Blog, Entry, Author, AuthorBio, Comment, TaggedItem, Project, ArtProject, ResearchProject, | ||
Company, | ||
) | ||
class TaggedItemSerializer(serializers.ModelSerializer): | ||
@@ -115,3 +121,40 @@ class Meta: | ||
model = Comment | ||
exclude = ('created_at', 'modified_at',) | ||
# fields = ('entry', 'body', 'author',) | ||
class ArtProjectSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = ArtProject | ||
exclude = ('polymorphic_ctype',) | ||
class ResearchProjectSerializer(serializers.ModelSerializer): | ||
class Meta: | ||
model = ResearchProject | ||
exclude = ('polymorphic_ctype',) | ||
class ProjectSerializer(serializers.PolymorphicModelSerializer): | ||
polymorphic_serializers = [ArtProjectSerializer, ResearchProjectSerializer] | ||
class Meta: | ||
model = Project | ||
exclude = ('polymorphic_ctype',) | ||
class CompanySerializer(serializers.ModelSerializer): | ||
current_project = relations.PolymorphicResourceRelatedField( | ||
ProjectSerializer, queryset=Project.objects.all()) | ||
future_projects = relations.PolymorphicResourceRelatedField( | ||
ProjectSerializer, queryset=Project.objects.all(), many=True) | ||
included_serializers = { | ||
'current_project': ProjectSerializer, | ||
'future_projects': ProjectSerializer, | ||
} | ||
class Meta: | ||
model = Company | ||
if version.parse(rest_framework.VERSION) >= version.parse('3.3'): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting... I had no idea it was possible to use an | ||
fields = '__all__' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -23,6 +23,7 @@ | ||
'django.contrib.auth', | ||
'django.contrib.admin', | ||
'rest_framework', | ||
'polymorphic', | ||
'example', | ||
] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This jumps straight into how to use polymorphic resources. While that is appropriate for a Usage page, if this is the only place in the documentation that describes polymorphic resources, I think an introductory paragraph providing context and why a user would need this would be beneficial. Also, are there going to be related packages that are needed for this work? If so, can we link to them? I'm thinking about
django-polymorphic
here.