Stars y Opinion se incluyeron en ListItem
Esto porque al final eran relaciones 1 a 1 y era preferible que estuvieran incluidos en un solo modelo, de esta forma hay menos llamadas a la base de datos desde la api y una api mas simple de realizar y llamar Realmente el unico modelo que quedo "extraño" es el de opinion helpfull que tendra que pasar a ser ... listitemhelpful? pero el nombre opinionhelpful es mas coherente
This commit is contained in:
@@ -12,7 +12,7 @@ class EntityForm(forms.ModelForm):
|
|||||||
class ListItemForm(forms.ModelForm):
|
class ListItemForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ListItem
|
model = ListItem
|
||||||
fields = ['entity', 'tags']
|
fields = ['entity', 'tags', 'stars', 'opinion']
|
||||||
|
|
||||||
|
|
||||||
class TagForm(forms.ModelForm):
|
class TagForm(forms.ModelForm):
|
||||||
|
|||||||
@@ -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
|
from django.conf import settings
|
||||||
|
import django.core.validators
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
|
||||||
@@ -25,33 +26,17 @@ class Migration(migrations.Migration):
|
|||||||
name='ListItem',
|
name='ListItem',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('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')),
|
('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(
|
migrations.CreateModel(
|
||||||
name='Tag',
|
name='Tag',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('name', models.CharField(max_length=50)),
|
('name', models.CharField(max_length=50)),
|
||||||
('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(
|
|
||||||
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)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
@@ -59,14 +44,14 @@ class Migration(migrations.Migration):
|
|||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('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)),
|
('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)),
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='listitem',
|
model_name='listitem',
|
||||||
name='tags',
|
name='tags',
|
||||||
field=models.ManyToManyField(to='lists.Tag'),
|
field=models.ManyToManyField(blank=True, related_name='list', to='lists.Tag'),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='listitem',
|
model_name='listitem',
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
"""Definición de los modelos que utilizara la aplicación Lists"""
|
"""Definición de los modelos que utilizara la aplicación Lists"""
|
||||||
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||||
|
|
||||||
from users.models import User
|
from users.models import User
|
||||||
from django.db.models import CharField, TextField, IntegerField
|
from django.db.models import CharField, TextField, IntegerField
|
||||||
from django.db.models import ForeignKey, ManyToManyField
|
from django.db.models import ForeignKey, ManyToManyField
|
||||||
@@ -29,25 +31,15 @@ class Tag(Model):
|
|||||||
|
|
||||||
class ListItem(Model):
|
class ListItem(Model):
|
||||||
"""Item de la lista de un usuario"""
|
"""Item de la lista de un usuario"""
|
||||||
|
stars_validators = [MinValueValidator(0), MaxValueValidator(5)]
|
||||||
|
|
||||||
user = ForeignKey(User, on_delete=CASCADE, related_name='list')
|
user = ForeignKey(User, on_delete=CASCADE, related_name='list')
|
||||||
entity = ForeignKey(Entity, on_delete=CASCADE)
|
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)
|
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):
|
class OpinionHelpful(Model):
|
||||||
"""Voto sobre una opinion"""
|
"""Voto sobre una opinion"""
|
||||||
VOTES = [
|
VOTES = [
|
||||||
@@ -57,5 +49,5 @@ class OpinionHelpful(Model):
|
|||||||
]
|
]
|
||||||
|
|
||||||
user = ForeignKey(User, on_delete=CASCADE)
|
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)
|
vote = CharField(max_length=1, choices=VOTES)
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ class TestList(TestCase):
|
|||||||
to_add = {
|
to_add = {
|
||||||
'entity': 'b',
|
'entity': 'b',
|
||||||
'entity_type': 'artist',
|
'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),
|
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.entity_id, to_add['entity'])
|
||||||
self.assertEqual(list_item.tags.count(), len(to_add['tags']))
|
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):
|
def test_delete_list_item_is_protected(self):
|
||||||
response = self.client.delete('/api/lists/list/1/1/')
|
response = self.client.delete('/api/lists/list/1/1/')
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ def list_item_view(request, user_id, list_item_id):
|
|||||||
list_item = list_item[0]
|
list_item = list_item[0]
|
||||||
|
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
return _get_list_item(request, user, list_item)
|
return _get_list_item(request, list_item)
|
||||||
if request.method == 'PUT':
|
if request.method == 'PUT':
|
||||||
return _update_list_item(request, user, list_item)
|
return _update_list_item(request, user, list_item)
|
||||||
elif request.method == 'DELETE':
|
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)
|
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"""
|
"""Obtiene un item de la lista del usuario"""
|
||||||
|
|
||||||
encoded_list_item = {
|
encoded_list_item = {
|
||||||
@@ -133,7 +133,9 @@ def _get_list_item(request, user, list_item):
|
|||||||
'tags': [{
|
'tags': [{
|
||||||
'id': tag.id,
|
'id': tag.id,
|
||||||
'name': tag.name
|
'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)
|
return JsonResponse(encoded_list_item)
|
||||||
|
|||||||
Reference in New Issue
Block a user