Commit f36a05f1 by Bill DeRusha Committed by Bill DeRusha

Add PersonWork model

parent e1b225b1
# pylint: disable=abstract-method
# pylint: disable=abstract-method,no-member
import datetime
import json
from urllib.parse import urlencode
......@@ -18,7 +18,7 @@ from course_discovery.apps.catalogs.models import Catalog
from course_discovery.apps.course_metadata.choices import CourseRunStatus, ProgramStatus
from course_discovery.apps.course_metadata.models import (
Course, CourseRun, Image, Organization, Person, Prerequisite, Seat, Subject, Video, Program, ProgramType, FAQ,
CorporateEndorsement, Endorsement, Position
CorporateEndorsement, Endorsement, Position, PersonWork
)
from course_discovery.apps.course_metadata.search_indexes import CourseIndex, CourseRunIndex, ProgramIndex
......@@ -211,25 +211,37 @@ class PersonSerializer(serializers.ModelSerializer):
"""Serializer for the ``Person`` model."""
position = PositionSerializer(required=False)
profile_image = StdImageSerializerField(required=False)
works = serializers.SlugRelatedField(many=True, read_only=True, slug_field='value', source='person_works')
@classmethod
def prefetch_queryset(cls):
return Person.objects.all().select_related('position__organization')
return Person.objects.all().select_related('position__organization').prefetch_related('person_works')
class Meta(object):
model = Person
fields = (
'uuid', 'given_name', 'family_name', 'bio', 'profile_image_url', 'slug', 'position', 'profile_image',
'partner',
'partner', 'works'
)
extra_kwargs = {
'partner': {'write_only': True}
}
def validate(self, data):
validated_data = super(PersonSerializer, self).validate(data)
validated_data['works'] = self.initial_data.get('works', [])
return validated_data
def create(self, validated_data):
position_data = validated_data.pop('position')
works_data = validated_data.pop('works')
person = Person.objects.create(**validated_data)
Position.objects.create(person=person, **position_data)
person_works = [PersonWork(person=person, value=work_data) for work_data in works_data]
PersonWork.objects.bulk_create(person_works)
return person
......
......@@ -1085,6 +1085,7 @@ class PersonSerializerTests(TestCase):
'profile_image_url': person.profile_image_url,
'profile_image': image_field.to_representation(person.profile_image),
'position': PositionSerializer(position).data,
'works': [work.value for work in person.person_works.all()],
'slug': person.slug,
}
......
......@@ -38,6 +38,7 @@ class PersonViewSetTests(SerializationMixin, APITestCase):
bio = "The maze is not for him."
title = "Park Director"
organization_id = self.organization.id
works = ["Delores", "Teddy", "Maive"]
data = {
'data': json.dumps(
......@@ -48,7 +49,8 @@ class PersonViewSetTests(SerializationMixin, APITestCase):
'position': {
'title': title,
'organization': organization_id
}
},
'works': works
}
)
}
......@@ -63,6 +65,7 @@ class PersonViewSetTests(SerializationMixin, APITestCase):
self.assertEqual(person.bio, bio)
self.assertEqual(person.position.title, title)
self.assertEqual(person.position.organization, self.organization)
self.assertEqual(sorted([work.value for work in person.person_works.all()]), sorted(works))
def test_create_without_authentication(self):
""" Verify authentication is required when creating a person. """
......
......@@ -65,7 +65,7 @@ class ProgramViewSetTests(SerializationMixin, APITestCase):
def test_retrieve(self):
""" Verify the endpoint returns the details for a single program. """
program = self.create_program()
with self.assertNumQueries(31):
with self.assertNumQueries(34):
response = self.assert_retrieve_success(program)
assert response.data == self.serialize_program(program)
......
......@@ -20,6 +20,11 @@ class PositionInline(admin.TabularInline):
extra = 0
class PersonWorkInline(admin.TabularInline):
model = PersonWork
extra = 0
class FaqsInline(admin.TabularInline):
model = Program.faq.through
exclude = ('sort_value',)
......@@ -192,7 +197,7 @@ class SubjectAdmin(admin.ModelAdmin):
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
inlines = (PositionInline,)
inlines = (PositionInline, PersonWorkInline,)
list_display = ('uuid', 'family_name', 'given_name', 'slug',)
list_filter = ('partner',)
ordering = ('family_name', 'given_name', 'uuid',)
......
# -*- coding: utf-8 -*-
# Generated by Django 1.9.11 on 2017-01-31 19:21
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import django_extensions.db.fields
class Migration(migrations.Migration):
dependencies = [
('course_metadata', '0046_courserun_reporting_type'),
]
operations = [
migrations.CreateModel(
name='PersonWork',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('value', models.CharField(max_length=255)),
('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='person_works', to='course_metadata.Person')),
],
options={
'abstract': False,
},
),
]
......@@ -891,3 +891,8 @@ class CourseRunSocialNetwork(AbstractSocialNetworkModel):
unique_together = (
('course_run', 'type'),
)
class PersonWork(AbstractValueModel):
""" Person Works model. """
person = models.ForeignKey(Person, related_name='person_works')
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-06 16:34-0500\n"
"POT-Creation-Date: 2017-02-06 20:07-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: apps/api/filters.py
#, python-brace-format
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-06 16:34-0500\n"
"POT-Creation-Date: 2017-02-06 20:07-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: static/js/catalogs-change-form.js
msgid "Preview"
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-06 16:34-0500\n"
"POT-Creation-Date: 2017-02-06 20:07-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps/api/filters.py
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-06 16:34-0500\n"
"POT-Creation-Date: 2017-02-06 20:07-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/js/catalogs-change-form.js
......
......@@ -72,7 +72,8 @@ $(document).ready(function(){
'position':{
'title': $('#title').val(),
'organization': parseInt($('#id_organization').val())
}
},
'works': $('#majorWorks').val().split('\n')
}
)
},
......@@ -81,7 +82,8 @@ $(document).ready(function(){
$('#family-name').val('');
$('#title').val('');
$('#bio').val('');
$('.select-image').attr('src', '')
$('.select-image').attr('src', '');
$('#majorWorks').val('');
clearModalError();
closeModal(e, $('#addInstructorModal'));
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment