Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Anthony
memopol
Commits
0731c495
Commit
0731c495
authored
Aug 29, 2016
by
Nicolas Joyard
Browse files
Add working position form
parent
f6d6bd9a
Changes
26
Show whitespace changes
Inline
Side-by-side
memopol/settings.py
View file @
0731c495
...
...
@@ -213,7 +213,7 @@ TEMPLATE_LOADERS = (
TEMPLATE_CONTEXT_PROCESSORS
=
global_settings
.
TEMPLATE_CONTEXT_PROCESSORS
+
(
'django.template.context_processors.request'
,
'memopol.context_processors.search_form_options'
'memopol.context_processors.search_form_options'
,
)
# Static files finders
...
...
memopol/tests/base.py
View file @
0731c495
...
...
@@ -7,13 +7,17 @@ class BaseTest(ResponseDiffTestMixin, test.TestCase):
"""
Common queries
- 5 for search forms
- 1 for chambers
- 1 for countries
- 1 for parties
- 1 for committees
- 1 for delegations
- 2 for the position form
- 1 for representatives
- 1 for themes
"""
left_pane_queries
=
5
left_pane_queries
=
7
def
request_test
(
self
,
url
=
None
):
self
.
assertResponseDiffEmpty
(
self
.
client
.
get
(
url
or
self
.
url
))
...
...
memopol/tests/response_fixtures/PositionFormTest.test_position_form.content
0 → 100644
View file @
0731c495
<form action="" method="post">
<div class="modal-header">
<button aria-label="Close" class="close" data-dismiss="modal" type="button"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Add a representative public position</h4>
</div>
<div class="modal-body">
<input name="csrfmiddlewaretoken" type="hidden" value="csrftoken"/>
<div class="row">
<div class="col-sm-12">
<div class="well well-sm text-justify">
<p>
Use this form to submit a public position taken by a representative and
related to one of the themes followed on this instance of Political Memory.
Public positions may include blog or social network posts, interviews,
parliament interventions...
</p>
<p>
Be sure to include a relevant excerpt from the public position as well as
a valid link that refers to it. Note that positions will be reviewed by
the staff before publication.
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group"><label class="col-md-3 control-label" for="id_position-representative">Representative</label><div class="col-md-9"><select class="form-control" id="id_position-representative" name="position-representative" required="required" title="">
<option selected="selected" value="">---------</option>
<option value="4902">François Asensi</option>
<option value="4893">Thierry Benoit</option>
<option value="4898">Marcel Bonnot</option>
<option value="4891">Jean-Claude Bouchet</option>
<option value="22">Paul BRANNEN</option>
<option value="12">Udo BULLMANN</option>
<option value="4914">Jean-Paul Chanteguet</option>
<option value="4912">Jean-Louis Christ</option>
<option value="4900">Jean-Michel Couve</option>
<option value="21">Esther de LANGE</option>
<option value="9">Albert DESS</option>
<option value="4896">Marc Dolez</option>
<option value="4889">Dominique Dord</option>
<option value="4899">Olivier Dussopt</option>
<option value="4890">Daniel Fasquelle</option>
<option value="24">María Teresa GIMÉNEZ BARBAT</option>
<option value="4894">Claude Goasguen</option>
<option value="4885">Pascale Got</option>
<option value="13">Bolesław G. PIECHA</option>
<option value="20">Iveta GRIGULE</option>
<option value="1">Czesław HOC</option>
<option value="4910">Philippe Houillon</option>
<option value="7">Sylvia-Yvonne KAUFMANN</option>
<option value="18">Jan KELLER</option>
<option value="3">Dietmar KÖSTER</option>
<option value="29">Werner LANGEN</option>
<option value="23">Jo LEINEN</option>
<option value="4903">Pierre Lellouche</option>
<option value="4886">Annick Lepetit</option>
<option value="4895">Pierre Lequiller</option>
<option value="8">Arne LIETZ</option>
<option value="19">Verónica LOPE FONTAGNÉ</option>
<option value="4908">Jacqueline Maquet</option>
<option value="4907">Philippe Martin</option>
<option value="25">Gesine MEISSNER</option>
<option value="4904">Hervé Morin</option>
<option value="4913">Alain Moyne-Bressand</option>
<option value="16">Angelika NIEBLER</option>
<option value="14">Paul NUTTALL</option>
<option value="5">Patrick O'FLYNN</option>
<option value="4905">Martine Pinville</option>
<option value="15">Mirosław PIOTROWSKI</option>
<option value="4906">François Pupponi</option>
<option value="4911">Jean-Luc Reitzer</option>
<option value="4909">Franck Reynier</option>
<option value="4888">Marcel Rogemont</option>
<option value="4901">André Santini</option>
<option value="10">Annie SCHREIJER-PIERIK</option>
<option value="28">Joachim SCHUSTER</option>
<option value="26">Helga STEVENS</option>
<option value="17">László TŐKÉS</option>
<option value="4887">Jean-Jacques Urvoas</option>
<option value="4892">Alain Vidalies</option>
<option value="4897">Philippe Vigier</option>
<option value="6">Axel VOSS</option>
<option value="2">Renate WEBER</option>
<option value="11">Kerstin WESTPHAL</option>
<option value="4">Hermann WINKLER</option>
<option value="27">Damiano ZOFFOLI</option>
</select></div></div>
<div class="form-group"><label class="col-md-3 control-label" for="id_position-datetime">Datetime</label><div class="col-md-9">
<div class="input-group date" id="id_position-datetime">
<input class="form-control" id="id_position-datetime" name="position-datetime" placeholder="Datetime" readonly="" required="required" title="" type="text"/>
<span class="input-group-addon"><span class="glyphicon glyphicon-remove"></span></span>
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
</div>
<script type="text/javascript">
$("#id_position-datetime").datetimepicker({minView: 2,
autoclose: true,
language: 'en',
startView: 2,
format: 'yyyy-mm-dd'}).find('input').addClass("form-control");
</script>
</div></div>
<div class="form-group"><label class="col-md-3 control-label" for="id_position-link">Link</label><div class="col-md-9"><input class="form-control" id="id_position-link" maxlength="500" name="position-link" placeholder="Link" required="required" title="" type="url"/></div></div>
</div>
<div class="col-sm-6">
<div class="form-group"><label class="col-md-3 control-label" for="id_position-themes_0">Themes</label><div class="col-md-9"><div id="id_position-themes"><div class="checkbox"><label for="id_position-themes_0"><input class="" id="id_position-themes_0" name="position-themes" title="" type="checkbox" value="1"/> Etat d'urgence</label></div>
<div class="checkbox"><label for="id_position-themes_1"><input class="" id="id_position-themes_1" name="position-themes" title="" type="checkbox" value="2"/> ACTA</label></div></div></div></div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="col-sm-12">
<div class="form-group"><label class="control-label" for="id_position-text">Text</label><textarea class="form-control" cols="40" id="id_position-text" name="position-text" placeholder="Text" required="required" rows="10" title=""></textarea></div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal" type="button">Close</button>
<button class="btn btn-primary" type="submit">Submit public position</button>
</div>
</form>
\ No newline at end of file
memopol/tests/response_fixtures/PositionFormTest.test_position_form.metadata
0 → 100644
View file @
0731c495
{
"status_code": 200
}
\ No newline at end of file
memopol/tests/response_fixtures/PositionFormTest.test_select_representative.content
0 → 100644
View file @
0731c495
<option selected="selected" value="4899">Olivier Dussopt</option>
\ No newline at end of file
memopol/tests/response_fixtures/PositionFormTest.test_select_representative.metadata
0 → 100644
View file @
0731c495
{
"status_code": 200
}
\ No newline at end of file
memopol/tests/response_fixtures/PositionFormTest.test_select_theme.content
0 → 100644
View file @
0731c495
<input checked="checked" class="" id="id_position-themes_0" name="position-themes" title="" type="checkbox" value="1"/>
\ No newline at end of file
memopol/tests/response_fixtures/PositionFormTest.test_select_theme.metadata
0 → 100644
View file @
0731c495
{
"status_code": 200
}
\ No newline at end of file
memopol/tests/test_position_form.py
0 → 100644
View file @
0731c495
from
.base
import
BaseTest
,
RepresentativeBaseTest
,
ThemeBaseTest
class
PositionFormTest
(
BaseTest
):
url
=
'/'
def
test_position_form
(
self
):
self
.
client
.
cookies
[
'csrftoken'
]
=
'csrftoken'
self
.
selector_test
(
'#add-position-form form'
)
def
test_select_representative
(
self
):
self
.
selector_test
(
'#add-position-form #id_position-representative option[selected]'
,
RepresentativeBaseTest
.
base_url
%
'none'
)
def
test_select_theme
(
self
):
self
.
selector_test
(
'#add-position-form #id_position-themes input[checked]'
,
ThemeBaseTest
.
base_url
%
'none'
)
memopol/urls.py
View file @
0731c495
# coding: utf-8
from
django.conf.urls
import
include
,
url
from
django.contrib
import
admin
from
django.views
import
generic
from
views.home
import
HomeView
from
views.dossier_ac
import
DossierAutocomplete
,
ProposalAutocomplete
from
views.dossier_detail_base
import
DossierDetailBase
...
...
@@ -184,8 +185,6 @@ urlpatterns = [
),
url
(
r
'^admin/'
,
include
(
admin
.
site
.
urls
)),
url
(
r
'^positions/'
,
include
(
'representatives_positions.urls'
,
namespace
=
'representatives_positions'
)),
url
(
r
'^api/'
,
include
(
api
.
router
.
urls
)),
url
(
r
'^$'
,
generic
.
TemplateView
.
as_view
(
template_name
=
'home.html'
)),
url
(
r
'^$'
,
HomeView
.
as_view
(
)),
]
memopol/views/dossier_detail_base.py
View file @
0731c495
...
...
@@ -4,8 +4,10 @@ from django.views import generic
from
representatives_votes.models
import
Dossier
from
representatives_positions.views
import
PositionFormMixin
class
DossierDetailBase
(
generic
.
DetailView
):
class
DossierDetailBase
(
PositionFormMixin
,
generic
.
DetailView
):
template_name
=
'representatives_votes/dossier_detail.html'
queryset
=
Dossier
.
objects
.
prefetch_related
(
'themes'
)
memopol/views/dossier_list.py
View file @
0731c495
...
...
@@ -9,8 +9,11 @@ from representatives_votes.models import Dossier
from
..filters
import
DossierFilter
from
representatives_positions.views
import
PositionFormMixin
class
DossierList
(
PaginationMixin
,
SortMixin
,
generic
.
ListView
):
class
DossierList
(
PaginationMixin
,
SortMixin
,
PositionFormMixin
,
generic
.
ListView
):
current_filter
=
None
queryset
=
Dossier
.
objects
.
prefetch_related
(
...
...
memopol/views/home.py
0 → 100644
View file @
0731c495
# coding: utf-8
from
django.views
import
generic
from
representatives_positions.views
import
PositionFormMixin
class
HomeView
(
PositionFormMixin
,
generic
.
TemplateView
):
template_name
=
'home.html'
memopol/views/representative_detail_base.py
View file @
0731c495
...
...
@@ -8,8 +8,11 @@ from representatives.models import Chamber, Representative, Address, Phone, \
from
.representative_mixin
import
RepresentativeViewMixin
from
representatives_positions.views
import
PositionFormMixin
class
RepresentativeDetailBase
(
RepresentativeViewMixin
,
generic
.
DetailView
):
class
RepresentativeDetailBase
(
RepresentativeViewMixin
,
PositionFormMixin
,
generic
.
DetailView
):
queryset
=
Representative
.
objects
.
select_related
(
'score'
)
...
...
@@ -56,5 +59,6 @@ class RepresentativeDetailBase(RepresentativeViewMixin, generic.DetailView):
c
=
super
(
RepresentativeDetailBase
,
self
).
get_context_data
(
**
kwargs
)
self
.
add_representative_country_and_main_mandate
(
c
[
'object'
])
c
[
'position_form'
].
fields
[
'representative'
].
initial
=
c
[
'object'
].
pk
return
c
memopol/views/representative_list.py
View file @
0731c495
...
...
@@ -10,10 +10,12 @@ from representatives.models import Representative
from
..filters
import
RepresentativeFilter
from
.representative_mixin
import
RepresentativeViewMixin
from
representatives_positions.views
import
PositionFormMixin
class
RepresentativeList
(
CSVDownloadMixin
,
GridListMixin
,
PaginationMixin
,
RepresentativeViewMixin
,
ActiveLegislatureMixin
,
SortMixin
,
generic
.
ListView
):
SortMixin
,
PositionFormMixin
,
generic
.
ListView
):
csv_name
=
'representatives'
queryset
=
Representative
.
objects
.
select_related
(
'score'
)
...
...
memopol/views/theme_detail_base.py
View file @
0731c495
...
...
@@ -4,8 +4,16 @@ from django.views import generic
from
memopol_themes.models
import
Theme
from
representatives_positions.views
import
PositionFormMixin
class
ThemeDetailBase
(
generic
.
DetailView
):
class
ThemeDetailBase
(
PositionFormMixin
,
generic
.
DetailView
):
template_name
=
'memopol_themes/theme_detail.html'
queryset
=
Theme
.
objects
.
all
()
def
get_context_data
(
self
,
**
kwargs
):
c
=
super
(
ThemeDetailBase
,
self
).
get_context_data
(
**
kwargs
)
c
[
'position_form'
].
fields
[
'themes'
].
initial
=
[
c
[
'object'
]]
return
c
memopol/views/theme_list.py
View file @
0731c495
...
...
@@ -9,8 +9,11 @@ from memopol_themes.models import Theme
from
..filters
import
ThemeFilter
from
representatives_positions.views
import
PositionFormMixin
class
ThemeList
(
PaginationMixin
,
SortMixin
,
generic
.
ListView
):
class
ThemeList
(
PaginationMixin
,
SortMixin
,
PositionFormMixin
,
generic
.
ListView
):
current_filter
=
None
queryset
=
Theme
.
objects
.
all
().
annotate
(
...
...
representatives_positions/forms.py
View file @
0731c495
...
...
@@ -2,21 +2,36 @@ from django import forms
from
datetimewidget.widgets
import
DateWidget
from
memopol_themes.models
import
Theme
from
.models
import
Position
class
PositionForm
(
forms
.
ModelForm
):
themes
=
forms
.
models
.
ModelMultipleChoiceField
(
queryset
=
Theme
.
objects
.
all
(),
required
=
False
,
widget
=
forms
.
CheckboxSelectMultiple
)
class
Meta
:
model
=
Position
fields
=
[
'datetime'
,
'text'
,
'link'
,
'representative'
]
fields
=
[
'representative'
,
'link'
,
'datetime'
,
'themes'
,
'text'
]
widgets
=
{
# Use localization and bootstrap 3
'datetime'
:
DateWidget
(
attrs
=
{
'id'
:
'yourdatetimeid'
},
usel10n
=
True
,
bootstrap_version
=
3
,
),
'representative'
:
forms
.
HiddenInput
bootstrap_version
=
3
)
}
def
save
(
self
,
commit
=
True
):
position
=
super
(
PositionForm
,
self
).
save
(
commit
=
False
)
if
commit
:
position
.
save
()
if
position
.
pk
:
position
.
themes
=
self
.
cleaned_data
.
get
(
'themes'
)
self
.
save_m2m
()
return
position
representatives_positions/models.py
View file @
0731c495
from
django.db
import
models
from
django.core.urlresolvers
import
reverse
from
django.template.defaultfilters
import
truncatewords
from
representatives.models
import
Representative
...
...
@@ -21,7 +20,3 @@ class Position(models.Model):
def
unpublish
(
self
):
self
.
published
=
False
def
get_absolute_url
(
self
):
return
reverse
(
'representatives_positions:position-detail'
,
args
=
(
self
.
pk
,))
representatives_positions/urls.py
deleted
100644 → 0
View file @
f6d6bd9a
from
django.conf.urls
import
url
import
views
urlpatterns
=
[
url
(
r
'^position/create/$'
,
views
.
PositionCreate
.
as_view
(),
name
=
'position-create'
),
url
(
r
'^position/(?P<pk>\d+)/$'
,
views
.
PositionDetail
.
as_view
(),
name
=
'position-detail'
),
]
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment