Commit 772b90c5 authored by Nicolas Joyard's avatar Nicolas Joyard

Add theme model, relations, and admin / Remove position tags

parent 69861a94
......@@ -1084,82 +1084,13 @@
"model": "representatives_recommendations.recommendation",
"pk": 47
},
{
"fields": {
"name": "acta",
"slug": "acta"
},
"model": "taggit.tag",
"pk": 1
},
{
"fields": {
"name": "foo",
"slug": "foo"
},
"model": "taggit.tag",
"pk": 2
},
{
"fields": {
"name": "bar",
"slug": "bar"
},
"model": "taggit.tag",
"pk": 3
},
{
"fields": {
"model": "position",
"app_label": "representatives_positions"
},
"model": "contenttypes.contenttype",
"pk": 29
},
{
"fields": {
"tag": 1,
"object_id": 1,
"content_type": 29
},
"model": "taggit.taggeditem",
"pk": 1
},
{
"fields": {
"tag": 2,
"object_id": 1,
"content_type": 29
},
"model": "taggit.taggeditem",
"pk": 2
},
{
"fields": {
"tag": 1,
"object_id": 3,
"content_type": 29
},
"model": "taggit.taggeditem",
"pk": 5
},
{
"fields": {
"tag": 1,
"object_id": 2,
"content_type": 29
},
"model": "taggit.taggeditem",
"pk": 6
},
{
"fields": {
"tag": 3,
"object_id": 2,
"content_type": 29
},
"model": "taggit.taggeditem",
"pk": 7
"pk": 31
},
{
"fields": {
......
......@@ -91,6 +91,7 @@ INSTALLED_APPS = (
'core',
'memopol',
'memopol_settings',
'memopol_themes',
'representatives',
'representatives_votes',
'representatives_recommendations',
......
......@@ -10,17 +10,6 @@
first-validated
</a>
</td>
<td>
<span class='label label-default'>
acta
</span>
<span class='label label-default'>
bar
</span>
</td>
<td>
<a href='http://example.com/first-validated'>
http://example.com/first-validated
......@@ -36,13 +25,6 @@
other-validated
</a>
</td>
<td>
<span class='label label-default'>
acta
</span>
</td>
<td>
<a href='http://example.com/second-validated'>
http://example.com/second-validated
......
......@@ -12,7 +12,7 @@ class RepresentativeDetailTest(UrlGetTestMixin, TestCase):
# Ensure one-time cached queries occur before the actual test
self.client.get(self.url)
with self.assertNumQueries(12):
with self.assertNumQueries(11):
"""
- One query for chambers
- One query for the rep details and foreign key (profile)
......@@ -24,7 +24,6 @@ class RepresentativeDetailTest(UrlGetTestMixin, TestCase):
- One query for reverse relation on votes
- One query for reverse relation on mandates
- One query for reverse relation positions
- One query for reverse relation tags on positions
"""
self.client.get(self.url)
......
......@@ -70,7 +70,6 @@ class RepresentativeDetail(RepresentativeViewMixin, generic.DetailView):
c['votes'] = c['object'].votes.all()
c['mandates'] = c['object'].mandates.all()
c['positions'] = c['object'].positions.filter(published=True) \
.prefetch_related('tags') \
.order_by('-datetime', 'pk')
c['position_form'] = PositionForm(
......
from django import forms
from django.contrib import admin
from representatives_votes.admin import DossierAdmin, ProposalAdmin
from representatives_votes.models import Dossier, Proposal
from representatives_positions.admin import PositionAdmin
from representatives_positions.models import Position
from .models import Theme, ThemeLink
class LinkInline(admin.StackedInline):
model = ThemeLink
extra = 0
class ThemeAdmin(admin.ModelAdmin):
list_display = ('name', 'description')
list_editable = ('name', 'description')
list_filter = ('name',)
fields = ('name', 'description')
inlines = [
LinkInline
]
class ThemeLinkAdmin(admin.ModelAdmin):
list_display = ('title', 'datetime', 'link')
list_editable = ('title', 'datetime', 'link')
list_filter = ('title', 'datetime', 'link')
class ThemedAdminForm(forms.ModelForm):
themes = forms.ModelMultipleChoiceField(
queryset=Theme.objects.all(),
required=False,
widget=admin.widgets.FilteredSelectMultiple(
verbose_name='Themes',
is_stacked=False
)
)
def __init__(self, *args, **kwargs):
super(ThemedAdminForm, self).__init__(*args, **kwargs)
if self.instance and self.instance.pk:
self.fields['themes'].initial = self.instance.themes.all()
def save(self, commit=True):
item = super(ThemedAdminForm, self).save(commit=False)
if commit:
item.save()
if item.pk:
item.themes = self.cleaned_data['themes']
self.save_m2m()
return item
class ThemedDossierAdminForm(ThemedAdminForm):
class Meta:
model = Dossier
fields = ('title', 'reference', 'text', 'themes')
class ThemedProposalAdminForm(ThemedAdminForm):
class Meta:
model = Proposal
fields = ('dossier', 'title', 'description', 'reference', 'datetime',
'kind', 'total_abstain', 'total_against', 'total_for',
'themes')
class ThemedPositionAdminForm(ThemedAdminForm):
class Meta:
model = Position
fields = ('representative', 'datetime', 'text', 'link', 'published',
'themes')
class ThemedDossierAdmin(DossierAdmin):
form = ThemedDossierAdminForm
class ThemedProposalAdmin(ProposalAdmin):
form = ThemedProposalAdminForm
class ThemedPositionAdmin(PositionAdmin):
form = ThemedPositionAdminForm
admin.site.register(Theme, ThemeAdmin)
admin.site.register(ThemeLink, ThemeLinkAdmin)
admin.site.unregister(Dossier)
admin.site.register(Dossier, ThemedDossierAdmin)
admin.site.unregister(Proposal)
admin.site.register(Proposal, ThemedProposalAdmin)
admin.site.unregister(Position)
admin.site.register(Position, ThemedPositionAdmin)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('representatives_votes', '0012_document'),
('representatives_positions', '0002_increase_link_length'),
]
operations = [
migrations.CreateModel(
name='Theme',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(unique=True, max_length=255)),
('description', models.TextField()),
('dossiers', models.ManyToManyField(related_name='themes', to='representatives_votes.Dossier')),
('positions', models.ManyToManyField(related_name='themes', to='representatives_positions.Position')),
('proposals', models.ManyToManyField(related_name='themes', to='representatives_votes.Proposal')),
],
),
migrations.CreateModel(
name='ThemeLink',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('title', models.CharField(max_length=511)),
('datetime', models.DateField()),
('link', models.URLField(max_length=500)),
('theme', models.ForeignKey(related_name='links', to='memopol_themes.Theme')),
],
),
]
from django.db import models
from django.utils.encoding import smart_unicode
from representatives_votes.models import Dossier, Proposal
from representatives_positions.models import Position
class Theme(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.TextField()
dossiers = models.ManyToManyField(Dossier, related_name='themes')
proposals = models.ManyToManyField(Proposal, related_name='themes')
positions = models.ManyToManyField(Position, related_name='themes')
def __unicode__(self):
return smart_unicode(self.name)
class ThemeLink(models.Model):
title = models.CharField(max_length=511)
datetime = models.DateField()
link = models.URLField(max_length=500)
theme = models.ForeignKey(Theme, related_name='links')
def __unicode__(self):
return smart_unicode('%s (%s)' % (self.title, self.link))
......@@ -8,7 +8,7 @@ from .models import Position
class PositionForm(forms.ModelForm):
class Meta:
model = Position
fields = ['tags', 'datetime', 'text', 'link', 'representative']
fields = ['datetime', 'text', 'link', 'representative']
widgets = {
# Use localization and bootstrap 3
'datetime': DateWidget(
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('representatives_positions', '0002_increase_link_length'),
]
operations = [
migrations.RemoveField(
model_name='position',
name='tags',
),
]
from django.db import models
from django.core.urlresolvers import reverse
from django.template.defaultfilters import truncatewords
from taggit.managers import TaggableManager
from representatives.models import Representative
class Position(models.Model):
representative = models.ForeignKey(Representative,
related_name='positions')
related_name='positions')
datetime = models.DateField()
text = models.TextField()
link = models.URLField(max_length=500)
published = models.BooleanField(default=False)
tags = TaggableManager()
@property
def short_text(self):
......@@ -26,4 +24,4 @@ class Position(models.Model):
def get_absolute_url(self):
return reverse('representatives_positions:position-detail',
args=(self.pk,))
args=(self.pk,))
......@@ -11,10 +11,7 @@
.long-quote
= object.text|linebreaks
%p.tags
- for tag in object.tags.all
%span.label.label-default
= tag
%p
Source :
%a{:href => '{{object.link}}'}
......
......@@ -13,13 +13,11 @@ class PositionTest(TestCase):
def setUp(self):
self.client = Client()
self.tags = [u'foo', u'bar']
self.create_url = reverse('representatives_positions:position-create')
self.mep = Representative.objects.get(pk=160)
self.fixture = {
'tags': ','.join(self.tags),
'datetime': '2015-12-11',
'text': '%stext' % self.id(),
'link': 'http://example.com/%slink' % self.id(),
......@@ -34,8 +32,6 @@ class PositionTest(TestCase):
assert response['Location'] == expected
result = Position.objects.get(text='%stext' % self.id())
assert list(result.tags.order_by('pk').values_list('name',
flat=True)) == self.tags
assert result.datetime == datetime.date(2015, 12, 11)
assert result.link == self.fixture['link']
assert result.representative.pk == self.mep.pk
......@@ -73,20 +69,16 @@ class PositionTest(TestCase):
representative=self.mep
)
position.tags.add('%stag' % self.id())
# Trigger irrelevant queries that happen only once ie. constance before
# testing actual page queries.
self.client.get(position.get_absolute_url())
with self.assertNumQueries(4):
with self.assertNumQueries(3):
# One for position and rep and score
# One for rep mandates
# One for rep chamber
# One for position tags
response = self.client.get(position.get_absolute_url())
assert 'Dec. 11, 2015' in response.content
assert '%stag' % self.id() in response.content
assert self.fixture['link'] in response.content
assert self.fixture['text'] in response.content
assert self.mep.full_name in response.content
......@@ -69,10 +69,6 @@
%td
%a{:href => '{{ position.get_absolute_url }}'}
=position.text|truncatewords:8
%td
- for tag in position.tags.all
%span.label.label-default
= tag
%td
%a{:href => '{{ position.link }}'}
= position.link
......
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