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:
Daniel Cortes
2020-07-14 10:31:32 -04:00
parent 1a36bec50a
commit ce76f76dfb
5 changed files with 52 additions and 42 deletions

View File

@@ -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):

View File

@@ -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',

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)