Commit 5f73e3c3 by Bill DeRusha Committed by Bill DeRusha

Add social network to serializer

parent ac43a015
......@@ -17,8 +17,9 @@ from course_discovery.apps.api.fields import ImageField, StdImageSerializerField
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 (FAQ, CorporateEndorsement, Course, CourseRun, Endorsement,
Image, Organization, Person, PersonWork, Position,
Prerequisite, Program, ProgramType, Seat, Subject, Video)
Image, Organization, Person, PersonSocialNetwork, PersonWork,
Position, Prerequisite, Program, ProgramType, Seat, Subject,
Video)
from course_discovery.apps.course_metadata.search_indexes import CourseIndex, CourseRunIndex, ProgramIndex
User = get_user_model()
......@@ -211,16 +212,19 @@ class PersonSerializer(serializers.ModelSerializer):
position = PositionSerializer(required=False)
profile_image = StdImageSerializerField(required=False)
works = serializers.SlugRelatedField(many=True, read_only=True, slug_field='value', source='person_works')
urls = serializers.SerializerMethodField()
@classmethod
def prefetch_queryset(cls):
return Person.objects.all().select_related('position__organization').prefetch_related('person_works')
return Person.objects.all().select_related(
'position__organization'
).prefetch_related('person_works', 'person_networks')
class Meta(object):
model = Person
fields = (
'uuid', 'given_name', 'family_name', 'bio', 'profile_image_url', 'slug', 'position', 'profile_image',
'partner', 'works'
'partner', 'works', 'urls'
)
extra_kwargs = {
'partner': {'write_only': True}
......@@ -229,20 +233,42 @@ class PersonSerializer(serializers.ModelSerializer):
def validate(self, data):
validated_data = super(PersonSerializer, self).validate(data)
validated_data['works'] = self.initial_data.get('works', [])
validated_data['urls'] = self.initial_data.get('urls')
return validated_data
def create(self, validated_data):
position_data = validated_data.pop('position')
works_data = validated_data.pop('works')
works_data = validated_data.pop('works', [])
urls_data = validated_data.pop('urls', {})
person = Person.objects.create(**validated_data)
Position.objects.create(person=person, **position_data)
person_social_networks = []
for url_type in [PersonSocialNetwork.FACEBOOK, PersonSocialNetwork.TWITTER, PersonSocialNetwork.BLOG]:
value = urls_data.get(url_type)
if value:
person_social_networks.append(PersonSocialNetwork(person=person, type=url_type, value=value))
PersonSocialNetwork.objects.bulk_create(person_social_networks)
person_works = [PersonWork(person=person, value=work_data) for work_data in works_data]
PersonWork.objects.bulk_create(person_works)
return person
def get_social_network_url(self, url_type, obj):
social_network = obj.person_networks.filter(type=url_type).first()
if social_network:
return social_network.value
def get_urls(self, obj):
return {
PersonSocialNetwork.FACEBOOK: self.get_social_network_url(PersonSocialNetwork.FACEBOOK, obj),
PersonSocialNetwork.TWITTER: self.get_social_network_url(PersonSocialNetwork.TWITTER, obj),
PersonSocialNetwork.BLOG: self.get_social_network_url(PersonSocialNetwork.BLOG, obj),
}
class EndorsementSerializer(serializers.ModelSerializer):
"""Serializer for the ``Endorsement`` model."""
......
......@@ -1117,6 +1117,11 @@ class PersonSerializerTests(TestCase):
'profile_image': image_field.to_representation(person.profile_image),
'position': PositionSerializer(position).data,
'works': [work.value for work in person.person_works.all()],
'urls': {
'facebook': None,
'twitter': None,
'blog': None
},
'slug': person.slug,
}
......
......@@ -39,6 +39,9 @@ class PersonViewSetTests(SerializationMixin, APITestCase):
title = "Park Director"
organization_id = self.organization.id
works = ["Delores", "Teddy", "Maive"]
facebook_url = 'http://www.facebook.com/hopkins'
twitter_url = 'http://www.twitter.com/hopkins'
blog_url = 'http://www.blog.com/hopkins'
data = {
'data': json.dumps(
......@@ -50,7 +53,12 @@ class PersonViewSetTests(SerializationMixin, APITestCase):
'title': title,
'organization': organization_id
},
'works': works
'works': works,
'urls': {
'facebook': facebook_url,
'twitter': twitter_url,
'blog': blog_url
}
}
)
}
......@@ -66,6 +74,10 @@ class PersonViewSetTests(SerializationMixin, APITestCase):
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))
self.assertEqual(
sorted([social.value for social in person.person_networks.all()]),
sorted([facebook_url, twitter_url, blog_url])
)
def test_create_without_authentication(self):
""" Verify authentication is required when creating a person. """
......
......@@ -64,7 +64,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(34):
with self.assertNumQueries(42):
response = self.assert_retrieve_success(program)
assert response.data == self.serialize_program(program)
......
......@@ -25,6 +25,11 @@ class PersonWorkInline(admin.TabularInline):
extra = 0
class PersonSocialNetworkInline(admin.TabularInline):
model = PersonSocialNetwork
extra = 0
class FaqsInline(admin.TabularInline):
model = Program.faq.through
exclude = ('sort_value',)
......@@ -197,7 +202,7 @@ class SubjectAdmin(admin.ModelAdmin):
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
inlines = (PositionInline, PersonWorkInline,)
inlines = (PositionInline, PersonWorkInline, PersonSocialNetworkInline)
list_display = ('uuid', 'family_name', 'given_name', 'slug',)
list_filter = ('partner',)
ordering = ('family_name', 'given_name', 'uuid',)
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-13 14:47+0500\n"
"POT-Creation-Date: 2017-02-13 07:55-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
......@@ -916,11 +916,19 @@ msgid "Bio"
msgstr ""
#: templates/publisher/_add_instructor_popup.html
msgid "Social Links"
msgid "Facebook URL"
msgstr ""
#: templates/publisher/_add_instructor_popup.html
msgid "optional - one per line"
msgid "optional"
msgstr ""
#: templates/publisher/_add_instructor_popup.html
msgid "Twitter URL"
msgstr ""
#: templates/publisher/_add_instructor_popup.html
msgid "Blog URL"
msgstr ""
#: templates/publisher/_add_instructor_popup.html
......@@ -928,6 +936,10 @@ msgid "Major Works"
msgstr ""
#: templates/publisher/_add_instructor_popup.html
msgid "optional - one per line"
msgstr ""
#: templates/publisher/_add_instructor_popup.html
msgid "Add Staff Member"
msgstr ""
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-13 14:47+0500\n"
"POT-Creation-Date: 2017-02-13 07:55-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-13 14:47+0500\n"
"POT-Creation-Date: 2017-02-13 07:55-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
......@@ -1071,18 +1071,30 @@ msgid "Bio"
msgstr "Bïö Ⱡ'σяєм#"
#: templates/publisher/_add_instructor_popup.html
msgid "Social Links"
msgstr "Söçïäl Lïnks Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
msgid "Facebook URL"
msgstr "Fäçéßöök ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
#: templates/publisher/_add_instructor_popup.html
msgid "optional - one per line"
msgstr "öptïönäl - öné pér lïné Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
msgid "optional"
msgstr "öptïönäl Ⱡ'σяєм ιρѕυм ∂#"
#: templates/publisher/_add_instructor_popup.html
msgid "Twitter URL"
msgstr "Twïttér ÛRL Ⱡ'σяєм ιρѕυм ∂σłσя #"
#: templates/publisher/_add_instructor_popup.html
msgid "Blog URL"
msgstr "Blög ÛRL Ⱡ'σяєм ιρѕυм ∂#"
#: templates/publisher/_add_instructor_popup.html
msgid "Major Works"
msgstr "Mäjör Wörks Ⱡ'σяєм ιρѕυм ∂σłσя #"
#: templates/publisher/_add_instructor_popup.html
msgid "optional - one per line"
msgstr "öptïönäl - öné pér lïné Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
#: templates/publisher/_add_instructor_popup.html
msgid "Add Staff Member"
msgstr "Àdd Stäff Mémßér Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-13 14:47+0500\n"
"POT-Creation-Date: 2017-02-13 07:55-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
......
......@@ -73,7 +73,12 @@ $(document).ready(function(){
'title': $('#title').val(),
'organization': parseInt($('#id_organization').val())
},
'works': $('#majorWorks').val().split('\n')
'works': $('#majorWorks').val().split('\n'),
'urls': {
'facebook': $('#facebook').val(),
'twitter': $('#twitter').val(),
'blog': $('#blog').val()
}
}
)
},
......@@ -84,6 +89,9 @@ $(document).ready(function(){
$('#bio').val('');
$('.select-image').attr('src', '');
$('#majorWorks').val('');
$('#facebook').val('');
$('#twitter').val('');
$('#blog').val('');
clearModalError();
closeModal(e, $('#addInstructorModal'));
},
......
......@@ -43,10 +43,20 @@
</label>
<textarea class="field-textarea input-textarea textarea-medium textarea-block" id="bio" name="bio"></textarea>
<label class="field-label" for="socialLinks">{% trans "Social Links" %}:
<span class="optional">({% trans "optional - one per line" %} )</span>
<label class="field-label" for="facebook">{% trans "Facebook URL" %}:
<span class="optional">* {% trans "optional" %}</span>
</label>
<input class="field-input input-text" type="text" id="facebook" name="facebook" />
<label class="field-label" for="twitter">{% trans "Twitter URL" %}:
<span class="optional">* {% trans "optional" %}</span>
</label>
<input class="field-input input-text" type="text" id="twitter" name="twitter" />
<label class="field-label" for="blog">{% trans "Blog URL" %}:
<span class="optional">* {% trans "optional" %}</span>
</label>
<textarea class="field-textarea input-textarea textarea-medium textarea-block" id="socialLinks" name="social-links"></textarea>
<input class="field-input input-text" type="text" id="blog" name="blog" />
<label class="field-label" for="majorWorks">{% trans "Major Works" %}:
<span class="optional">({% trans "optional - one per line" %} )</span>
......
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