diff --git a/lists/forms.py b/lists/forms.py index 3cdb451..86c0bbd 100644 --- a/lists/forms.py +++ b/lists/forms.py @@ -12,7 +12,7 @@ class EntityForm(forms.ModelForm): class ListItemForm(forms.ModelForm): class Meta: model = ListItem - fields = ['entity', 'tags'] + fields = ['entity', 'tags', 'stars', 'opinion'] class TagForm(forms.ModelForm): diff --git a/lists/migrations/0001_initial.py b/lists/migrations/0001_initial.py index bd9c4ae..f116293 100644 --- a/lists/migrations/0001_initial.py +++ b/lists/migrations/0001_initial.py @@ -1,6 +1,7 @@ -# Generated by Django 3.0.7 on 2020-06-28 22:41 +# Generated by Django 3.0.7 on 2020-07-14 14:27 from django.conf import settings +import django.core.validators from django.db import migrations, models import django.db.models.deletion @@ -25,33 +26,17 @@ class Migration(migrations.Migration): name='ListItem', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('stars', models.IntegerField(default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(5)])), + ('opinion', models.TextField(default='')), ('entity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lists.Entity')), ], ), - migrations.CreateModel( - name='Opinion', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('opinion_text', models.TextField()), - ('entity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lists.ListItem')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), migrations.CreateModel( name='Tag', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=50)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='Stars', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('quantity', models.IntegerField()), - ('entity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lists.ListItem')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tags', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( @@ -59,14 +44,14 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('vote', models.CharField(choices=[('Y', 'Si'), ('N', 'No'), ('F', 'Divertida')], max_length=1)), - ('opinion', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lists.Opinion')), + ('opinion', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lists.ListItem')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), migrations.AddField( model_name='listitem', name='tags', - field=models.ManyToManyField(to='lists.Tag'), + field=models.ManyToManyField(blank=True, related_name='list', to='lists.Tag'), ), migrations.AddField( model_name='listitem', diff --git a/lists/models.py b/lists/models.py index 5d8a554..60d9eb2 100644 --- a/lists/models.py +++ b/lists/models.py @@ -1,4 +1,6 @@ """Definición de los modelos que utilizara la aplicación Lists""" +from django.core.validators import MinValueValidator, MaxValueValidator + from users.models import User from django.db.models import CharField, TextField, IntegerField from django.db.models import ForeignKey, ManyToManyField @@ -29,25 +31,15 @@ class Tag(Model): class ListItem(Model): """Item de la lista de un usuario""" + stars_validators = [MinValueValidator(0), MaxValueValidator(5)] + user = ForeignKey(User, on_delete=CASCADE, related_name='list') entity = ForeignKey(Entity, on_delete=CASCADE) + stars = IntegerField(default=0, validators=stars_validators, blank=True) + opinion = TextField(default='', blank=True) tags = ManyToManyField(Tag, related_name='list', blank=True) -class Stars(Model): - """Estrellas que un usuario le asigno a una entidad""" - user = ForeignKey(User, on_delete=CASCADE) - entity = ForeignKey(ListItem, on_delete=CASCADE) - quantity = IntegerField() - - -class Opinion(Model): - """Opinion de un usuario sobre una entidad""" - user = ForeignKey(User, on_delete=CASCADE) - entity = ForeignKey(ListItem, on_delete=CASCADE) - opinion_text = TextField() - - class OpinionHelpful(Model): """Voto sobre una opinion""" VOTES = [ @@ -57,5 +49,5 @@ class OpinionHelpful(Model): ] user = ForeignKey(User, on_delete=CASCADE) - opinion = ForeignKey(Opinion, on_delete=CASCADE) + opinion = ForeignKey(ListItem, on_delete=CASCADE) vote = CharField(max_length=1, choices=VOTES) diff --git a/lists/test.py b/lists/test.py index ab5a3fa..a1af917 100644 --- a/lists/test.py +++ b/lists/test.py @@ -68,7 +68,9 @@ class TestList(TestCase): to_add = { 'entity': 'b', 'entity_type': 'artist', - 'tags': ['1', '2'] + 'tags': ['1', '2'], + 'stars': 1, + 'opinion': 'oh no' } response = self.client.post('/api/lists/list/1/', json.dumps(to_add), @@ -133,6 +135,35 @@ class TestList(TestCase): self.assertEqual(list_item.entity_id, to_add['entity']) self.assertEqual(list_item.tags.count(), len(to_add['tags'])) + def test_add_to_list_non_valid_stars(self): + to_add = { + 'entity': 'b', + 'entity_type': 'artist', + 'tags': ['1', '2'], + 'stars': -1, + 'opinion': 'oh no' + } + + response = self.client.post('/api/lists/list/1/', json.dumps(to_add), + content_type='application/json', + HTTP_AUTHORIZATION=self._user_bearer_token()) + + self.assertEqual(response.status_code, 400) + + to_add = { + 'entity': 'b', + 'entity_type': 'artist', + 'tags': ['1', '2'], + 'stars': 6, + 'opinion': 'oh no' + } + + response = self.client.post('/api/lists/list/1/', json.dumps(to_add), + content_type='application/json', + HTTP_AUTHORIZATION=self._user_bearer_token()) + + self.assertEqual(response.status_code, 400) + def test_delete_list_item_is_protected(self): response = self.client.delete('/api/lists/list/1/1/') self.assertEqual(response.status_code, 403) diff --git a/lists/views.py b/lists/views.py index 399f88f..a92c74f 100644 --- a/lists/views.py +++ b/lists/views.py @@ -113,7 +113,7 @@ def list_item_view(request, user_id, list_item_id): list_item = list_item[0] if request.method == 'GET': - return _get_list_item(request, user, list_item) + return _get_list_item(request, list_item) if request.method == 'PUT': return _update_list_item(request, user, list_item) elif request.method == 'DELETE': @@ -122,7 +122,7 @@ def list_item_view(request, user_id, list_item_id): return JsonResponse({'status': 404, 'error': 'La ruta no existe'}, status=404) -def _get_list_item(request, user, list_item): +def _get_list_item(request, list_item): """Obtiene un item de la lista del usuario""" encoded_list_item = { @@ -133,7 +133,9 @@ def _get_list_item(request, user, list_item): 'tags': [{ 'id': tag.id, 'name': tag.name - } for tag in list_item.tags.all()] + } for tag in list_item.tags.all()], + 'stars': list_item.stars, + 'opinion': list_item.opinion } return JsonResponse(encoded_list_item)