From b6d979fba214a9c264efd3d1c2881e0a31511c02 Mon Sep 17 00:00:00 2001 From: David Silva Date: Mon, 8 Oct 2018 18:05:52 -0400 Subject: [PATCH 1/2] Removed Source class, consolidated on attachments --- challenges/migrations/0001_initial.py | 29 +++++++++---------- challenges/migrations/0002_challenge_tags.py | 18 ------------ challenges/models.py | 26 ++++++++++------- challenges/serializers.py | 23 ++++++++------- .../tests/test_requests/test_challenges.py | 17 ++++++----- challenges/views.py | 11 +++++-- 6 files changed, 60 insertions(+), 64 deletions(-) delete mode 100644 challenges/migrations/0002_challenge_tags.py diff --git a/challenges/migrations/0001_initial.py b/challenges/migrations/0001_initial.py index c13ee9b..0bae746 100644 --- a/challenges/migrations/0001_initial.py +++ b/challenges/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.2 on 2018-10-07 00:29 +# Generated by Django 2.1.2 on 2018-10-08 22:58 from django.conf import settings from django.db import migrations, models @@ -23,6 +23,7 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=250)), ('url', models.TextField()), ('active', models.BooleanField(default=True)), + ('attachment_type', models.CharField(blank=True, choices=[('image', 'Image'), ('github_url', 'Github Url'), ('url', 'Url'), ('zip', 'Zip'), ('pdf', 'PDF'), ('Sketch', 'Sketch File'), ('PSD', 'Photoshop')], max_length=30, null=True)), ], ), migrations.CreateModel( @@ -44,19 +45,7 @@ class Migration(migrations.Migration): ('technical_notes', models.TextField()), ('procedure', models.TextField()), ('code_tips', models.TextField()), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='Source', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=250)), - ('url', models.TextField()), - ('active', models.BooleanField(default=True)), - ('challenge', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='challenges.Challenge')), + ('fake_date_created', models.CharField(max_length=25, null=True)), ], ), migrations.CreateModel( @@ -68,9 +57,19 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=250)), ], ), + migrations.AddField( + model_name='challenge', + name='tags', + field=models.ManyToManyField(related_name='challenges', to='challenges.Tag'), + ), + migrations.AddField( + model_name='challenge', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL), + ), migrations.AddField( model_name='attachment', name='challenge', - field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='challenges.Challenge'), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='challenges.Challenge'), ), ] diff --git a/challenges/migrations/0002_challenge_tags.py b/challenges/migrations/0002_challenge_tags.py deleted file mode 100644 index 7459e14..0000000 --- a/challenges/migrations/0002_challenge_tags.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.1.2 on 2018-10-07 16:35 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('challenges', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='challenge', - name='tags', - field=models.ManyToManyField(related_name='challenges', to='challenges.Tag'), - ), - ] diff --git a/challenges/models.py b/challenges/models.py index abec8b3..af95464 100644 --- a/challenges/models.py +++ b/challenges/models.py @@ -1,6 +1,7 @@ from django.db import models from accounts.models import User + class Tag(models.Model): def __str__(self): return self.name @@ -9,6 +10,7 @@ def __str__(self): updated_at = models.DateTimeField(auto_now=True) name = models.CharField(max_length=250,) + class Challenge(models.Model): CHALLENGE_TYPES = ( @@ -36,25 +38,27 @@ class Challenge(models.Model): procedure = models.TextField() code_tips = models.TextField() tags = models.ManyToManyField(Tag, related_name='challenges') + fake_date_created = models.CharField(max_length=25, null=True) + class Attachment(models.Model): def __str__(self): return self.name - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - name = models.CharField(max_length=250,) - url = models.TextField() - active = models.BooleanField(default=True) - challenge = models.ForeignKey(Challenge, on_delete=models.DO_NOTHING) - -class Source(models.Model): - def __str__(self): - return self.name + ATTACHMENT_TYPES = ( + ('image', 'Image'), + ('github_url', 'Github Url'), + ('url', 'Url'), + ('zip', 'Zip'), + ('pdf', 'PDF'), + ('Sketch', 'Sketch File'), + ('PSD', 'Photoshop'), + ) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) name = models.CharField(max_length=250,) url = models.TextField() active = models.BooleanField(default=True) - challenge = models.ForeignKey(Challenge, related_name='sources', on_delete=models.DO_NOTHING) + attachment_type = models.CharField(max_length=30, choices=ATTACHMENT_TYPES, null=True, blank=True) + challenge = models.ForeignKey(Challenge, related_name='attachments', on_delete=models.CASCADE) diff --git a/challenges/serializers.py b/challenges/serializers.py index 37b91a8..bffc6b9 100644 --- a/challenges/serializers.py +++ b/challenges/serializers.py @@ -1,5 +1,5 @@ from rest_framework_json_api import serializers -from .models import Challenge, Tag, Source +from .models import Challenge, Tag, Attachment from accounts.models import User from accounts.serializers import UserSerializer from rest_framework_json_api.relations import ResourceRelatedField @@ -9,25 +9,28 @@ class Meta: model = Tag fields = ('name',) -class SourcesSerializer(serializers.ModelSerializer): - queryset = Source.objects.filter(active=True,) +class AttachmentsSerializer(serializers.ModelSerializer): + + queryset = Attachment.objects.filter(active=True,) class Meta: - model = Source - fields = ('name', 'url') + model = Attachment + fields = ('name', 'url', 'attachment_type') class ChallengeSerializer(serializers.ModelSerializer): class Meta: model = Challenge - fields = ('user', 'tags', 'sources', 'created_at', 'updated_at', 'title', 'short_title', 'owner', 'difficulty', + fields = ('user', 'tags', 'attachments', 'created_at', 'updated_at', 'title', 'short_title', 'owner', 'difficulty', 'challenge_type', 'priority', 'description', 'short_description', 'extra_points', 'technical_notes', 'procedure', 'code_tips') + queryset = Challenge.objects.filter(is_visible=True,) + included_serializers = { 'user': UserSerializer, 'tags': TagsSerializer, - 'sources': SourcesSerializer, + 'attachments': AttachmentsSerializer, } user = ResourceRelatedField( @@ -39,13 +42,13 @@ class Meta: many=True, ) - sources = ResourceRelatedField( - queryset=Source.objects, + attachments = ResourceRelatedField( + queryset=Attachment.objects, many=True, ) class JSONAPIMeta: - included_resources = ['user', 'tags', 'sources'] + included_resources = ['user', 'tags', 'attachments'] class TagGetSerializer(serializers.ModelSerializer): class Meta: diff --git a/challenges/tests/test_requests/test_challenges.py b/challenges/tests/test_requests/test_challenges.py index 2aaa0b6..c66b205 100644 --- a/challenges/tests/test_requests/test_challenges.py +++ b/challenges/tests/test_requests/test_challenges.py @@ -1,7 +1,7 @@ from django.test import TestCase from rest_framework.test import APIClient, APITestCase from accounts.models import User -from challenges.models import Challenge, Tag, Attachment, Source +from challenges.models import Challenge, Tag, Attachment import sure import json import pdb @@ -56,7 +56,7 @@ def test_challenge_create_with_tags(self): """ Ensure we get the correct tags information with a challenge """ - tag1 = Tag.objects.create(name='Javascript') + tag1 = Tag.objects.create(name='JavascriptTestTag') challenge = self.get_sample_challenge(tags=[ tag1 ]) @@ -73,15 +73,16 @@ def test_challenge_create_with_tags(self): [item for item in included if item.get('type') == 'tags'][0]['attributes']['name'].should.equal(tag1.name) - def test_challenge_create_with_source(self): + def test_challenge_create_with_attachment(self): """ - Ensure we get the correct sources information with the challenge + Ensure we get the correct attachments information with the challenge """ challenge = self.get_sample_challenge() - source = Source.objects.create( + attachment = Attachment.objects.create( challenge=challenge, name='github', - url='https://github.com/corgicode' + attachment_type='github_url', + url='https://github.com/corgicode', ) response = self.client.get(f'/services/api/challenges?pk={ challenge.id }', @@ -92,13 +93,13 @@ def test_challenge_create_with_source(self): response_data = json.loads(response.content) included = response_data['included'] - [item for item in included if item.get('type') == 'sources'][0]['attributes']['name'].should.equal(source.name) + [item for item in included if item.get('type') == 'attachments'][0]['attributes']['name'].should.equal(attachment.name) def get_challenges_with_tag_name(self): """ Ensure we get the correct challenge """ - tag = Tag.objects.create(name='testTag') + tag = Tag.objects.create(name='testTagName') challenge1 = self.get_sample_challenge(tags=[ tag ]) challenge2 = self.get_sample_challenge(tags=[ tag ]) diff --git a/challenges/views.py b/challenges/views.py index 6104289..1bdc5d6 100644 --- a/challenges/views.py +++ b/challenges/views.py @@ -5,7 +5,7 @@ class ChallengesViewSet(viewsets.ModelViewSet): def get_queryset(self): - queryset = Challenge.objects.all() + queryset = Challenge.objects.filter(is_visible=True,).order_by('id') pk = self.request.query_params.get('pk', None) if pk is not None: queryset = queryset.filter(pk=pk) @@ -13,13 +13,20 @@ def get_queryset(self): serializer_class = ChallengeSerializer + class Meta: + ordering = ['-id'] + class TagsViewSet(viewsets.ModelViewSet): def get_queryset(self): - queryset = Tag.objects.all() + queryset = Tag.objects.all().order_by('id') pk = self.request.query_params.get('name', None) if pk is not None: queryset = queryset.filter(name=name) return queryset serializer_class = TagGetSerializer + + class Meta: + ordering = ['-id'] + From aeb7d9adbfed33baaf0727e6c3c13da7eebb52a9 Mon Sep 17 00:00:00 2001 From: David Silva Date: Wed, 17 Oct 2018 00:12:08 -0400 Subject: [PATCH 2/2] Added container names to docker-compose to use a docker debugger plugin with vscode, ignoring .history to use a local history plugin --- .gitignore | 3 ++- docker-compose.yml | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index aa1db36..d82a9d8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ __pycache__/ .DS_Store .envrc .vscode -data/postgres \ No newline at end of file +data/postgres +.history \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index ae83052..1b9817f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,6 +2,7 @@ version: '3' services: db: + container_name: corgi-pg image: postgres ports: - "5432:5432" @@ -13,6 +14,7 @@ services: - POSTGRES_USER=dbUsername - POSTGRES_DB=dbName web: + container_name: corgi-web build: . command: ./entrypoint.sh volumes: