Commit 1ed16776 authored by Nicolas Joyard's avatar Nicolas Joyard

Fix API inconsistencies

parent 8a009043
......@@ -10,6 +10,7 @@ from rest_framework import (
from representatives.serializers import (
ChamberSerializer,
ConstituencySerializer,
CountrySerializer,
GroupSerializer,
MandateSerializer,
RepresentativeDetailSerializer,
......@@ -20,6 +21,7 @@ from .models import (
Address,
Chamber,
Constituency,
Country,
Group,
Mandate,
Phone,
......@@ -129,3 +131,9 @@ class ChamberViewSet(viewsets.ReadOnlyModelViewSet):
pagination_class = DefaultWebPagination
queryset = Chamber.objects.all()
serializer_class = ChamberSerializer
class CountryViewSet(viewsets.ReadOnlyModelViewSet):
pagination_class = DefaultWebPagination
queryset = Country.objects.all()
serializer_class = CountrySerializer
# coding: utf-8
from django.db import transaction
from rest_framework import serializers
import representatives.models as models
class CountrySerializer(serializers.ModelSerializer):
class CountrySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Country
fields = ('name', 'code')
fields = ('id', 'url', 'name', 'code')
extra_kwargs = {
'url': {'view_name': 'api-country-detail'}
}
class ChamberSerializer(serializers.ModelSerializer):
class ChamberSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Chamber
fields = ('name', 'abbreviation', 'country')
fields = ('id', 'url', 'name', 'abbreviation', 'country')
extra_kwargs = {
'url': {'view_name': 'api-chamber-detail'},
'country': {'view_name': 'api-country-detail'}
}
class EmailSerializer(serializers.ModelSerializer):
class EmailSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Email
......@@ -75,43 +81,33 @@ class ContactField(serializers.Serializer):
}
class ConstituencySerializer(serializers.ModelSerializer):
class ConstituencySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Constituency
fields = ('id', 'name')
fields = ('id', 'url', 'name')
extra_kwargs = {
'url': {'view_name': 'api-constituency-detail'}
}
class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = models.Group
fields = ('id', 'name', 'abbreviation', 'kind')
class MandateSerializer(serializers.ModelSerializer):
fields = ('id', 'url', 'name', 'abbreviation', 'kind')
extra_kwargs = {
'url': {'view_name': 'api-group-detail'}
}
# name = serializers.CharField(source='group.name')
# short_id = serializers.CharField(
# source='group.abbreviation', allow_blank=True)
# kind = serializers.CharField(source='group.kind')
# constituency = serializers.CharField(source='constituency.name')
group = serializers.CharField(
source='group.id',
)
constituency = serializers.CharField(
source='constituency.id'
)
representative = serializers.CharField(
source='representative.id'
)
class MandateSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
depth = 1
model = models.Mandate
fields = (
'id',
'url',
'representative',
'group',
'constituency',
......@@ -120,6 +116,13 @@ class MandateSerializer(serializers.ModelSerializer):
'end_date',
)
extra_kwargs = {
'url': {'view_name': 'api-mandate-detail'},
'group': {'view_name': 'api-group-detail'},
'constituency': {'view_name': 'api-constituency-detail'},
'representative': {'view_name': 'api-representative-detail'}
}
def to_internal_value(self, data):
data = super(MandateSerializer, self).to_internal_value(data)
data['group'] = models.Group.objects.get(
......@@ -141,6 +144,7 @@ class MandateDetailSerializer(MandateSerializer):
class Meta(MandateSerializer.Meta):
fields = (
'id',
'url',
'group',
'constituency',
'role',
......@@ -149,13 +153,14 @@ class MandateDetailSerializer(MandateSerializer):
)
class RepresentativeSerializer(serializers.ModelSerializer):
class RepresentativeSerializer(serializers.HyperlinkedModelSerializer):
contacts = ContactField()
class Meta:
model = models.Representative
fields = (
'id',
'url',
'slug',
'first_name',
'last_name',
......@@ -167,62 +172,10 @@ class RepresentativeSerializer(serializers.ModelSerializer):
'active',
'cv',
'contacts',
'url',
)
@transaction.atomic
def create(self, validated_data):
contacts_data = validated_data.pop('contacts')
representative = models.Representative.objects.create(
**validated_data
)
self._create_contacts(contacts_data, representative)
return representative
@transaction.atomic
def update(self, instance, validated_data):
contacts_data = validated_data.pop('contacts')
for attr, value in validated_data.iteritems():
setattr(instance, attr, value)
instance.save()
self._create_contacts(contacts_data, instance)
return instance
def touch_model(self, model, **data):
'''
This method create or look up a model with the given data
it saves the given model if it exists, updating its
updated field
'''
instance, created = model.objects.get_or_create(**data)
if not created:
instance.save()
return (instance, created)
def _create_contacts(self, contacts_data, representative):
for contact_data in contacts_data['emails']:
contact_data['representative'] = representative
self.touch_model(model=models.Email, **contact_data)
for contact_data in contacts_data['websites']:
contact_data['representative'] = representative
self.touch_model(model=models.WebSite, **contact_data)
for contact_data in contacts_data['address']:
country, _ = models.Country.objects.get_or_create(
**contact_data.pop('country')
)
phone_set = contact_data.pop('phones')
contact_data['representative'] = representative
contact_data['country'] = country
contact, _ = self.touch_model(model=models.Address, **contact_data)
for phone_data in phone_set:
phone_data['representative'] = representative
phone_data['address'] = contact
self.touch_model(model=models.Phone, **phone_data)
extra_kwargs = {
'url': {'view_name': 'api-representative-detail'},
}
class RepresentativeDetailSerializer(RepresentativeSerializer):
......
[{"name":"European Parliament","abbreviation":"EP","country":null}]
\ No newline at end of file
[{"id":1,"url":"http://testserver/api/chambers/1/?format=json","name":"European Parliament","abbreviation":"EP","country":null}]
\ No newline at end of file
[{"id":1,"name":"European Parliament"},{"id":2,"name":"Österreichische Volkspartei"},{"id":3,"name":"Arbetarepartiet- Socialdemokraterna"}]
\ No newline at end of file
[{"id":1,"url":"http://testserver/api/constituencies/1/?format=json","name":"European Parliament"},{"id":2,"url":"http://testserver/api/constituencies/2/?format=json","name":"Österreichische Volkspartei"},{"id":3,"url":"http://testserver/api/constituencies/3/?format=json","name":"Arbetarepartiet- Socialdemokraterna"}]
\ No newline at end of file
[{"id":6,"name":"Austria","abbreviation":"AT","kind":"country"},{"id":8,"name":"Committee on Economic and Monetary Affairs","abbreviation":"ECON","kind":"committee"},{"id":1,"name":"Committee on Employment and Social Affairs","abbreviation":"EMPL","kind":"committee"},{"id":9,"name":"Committee on Industry, Research and Energy","abbreviation":"ITRE","kind":"committee"},{"id":7,"name":"Conference of Delegation Chairs","abbreviation":"","kind":"organization"},{"id":12,"name":"Delegation for relations with Australia and New Zealand","abbreviation":"","kind":"delegation"},{"id":11,"name":"Delegation for relations with Bosnia and Herzegovina, and Kosovo","abbreviation":"","kind":"delegation"},{"id":3,"name":"Delegation for relations with the Member States of ASEAN, South-east Asia and the Republic of Korea","abbreviation":"","kind":"delegation"},{"id":2,"name":"Delegation for relations with the countries of Southeast Asia and the Association of Southeast Asian Nations (ASEAN)","abbreviation":"","kind":"delegation"},{"id":10,"name":"Delegation to the EU-Serbia Stabilisation and Association Parliamentary Committee","abbreviation":"","kind":"delegation"},{"id":4,"name":"Group of the European People's Party (Christian Democrats) and European Democrats","abbreviation":"PPE-DE","kind":"group"},{"id":5,"name":"Group of the European People's Party (Christian-Democratic Group)","abbreviation":"EPP","kind":"group"},{"id":13,"name":"Group of the Progressive Alliance of Socialists and Democrats in the European Parliament","abbreviation":"SD","kind":"group"},{"id":14,"name":"Sweden","abbreviation":"SE","kind":"country"}]
\ No newline at end of file
[{"id":6,"url":"http://testserver/api/groups/6/?format=json","name":"Austria","abbreviation":"AT","kind":"country"},{"id":8,"url":"http://testserver/api/groups/8/?format=json","name":"Committee on Economic and Monetary Affairs","abbreviation":"ECON","kind":"committee"},{"id":1,"url":"http://testserver/api/groups/1/?format=json","name":"Committee on Employment and Social Affairs","abbreviation":"EMPL","kind":"committee"},{"id":9,"url":"http://testserver/api/groups/9/?format=json","name":"Committee on Industry, Research and Energy","abbreviation":"ITRE","kind":"committee"},{"id":7,"url":"http://testserver/api/groups/7/?format=json","name":"Conference of Delegation Chairs","abbreviation":"","kind":"organization"},{"id":12,"url":"http://testserver/api/groups/12/?format=json","name":"Delegation for relations with Australia and New Zealand","abbreviation":"","kind":"delegation"},{"id":11,"url":"http://testserver/api/groups/11/?format=json","name":"Delegation for relations with Bosnia and Herzegovina, and Kosovo","abbreviation":"","kind":"delegation"},{"id":3,"url":"http://testserver/api/groups/3/?format=json","name":"Delegation for relations with the Member States of ASEAN, South-east Asia and the Republic of Korea","abbreviation":"","kind":"delegation"},{"id":2,"url":"http://testserver/api/groups/2/?format=json","name":"Delegation for relations with the countries of Southeast Asia and the Association of Southeast Asian Nations (ASEAN)","abbreviation":"","kind":"delegation"},{"id":10,"url":"http://testserver/api/groups/10/?format=json","name":"Delegation to the EU-Serbia Stabilisation and Association Parliamentary Committee","abbreviation":"","kind":"delegation"},{"id":4,"url":"http://testserver/api/groups/4/?format=json","name":"Group of the European People's Party (Christian Democrats) and European Democrats","abbreviation":"PPE-DE","kind":"group"},{"id":5,"url":"http://testserver/api/groups/5/?format=json","name":"Group of the European People's Party (Christian-Democratic Group)","abbreviation":"EPP","kind":"group"},{"id":13,"url":"http://testserver/api/groups/13/?format=json","name":"Group of the Progressive Alliance of Socialists and Democrats in the European Parliament","abbreviation":"SD","kind":"group"},{"id":14,"url":"http://testserver/api/groups/14/?format=json","name":"Sweden","abbreviation":"SE","kind":"country"}]
\ No newline at end of file
[{"id":9,"representative":"2","group":"8","constituency":"1","role":"Member","begin_date":"2014-07-01","end_date":"9999-12-31"},{"id":10,"representative":"2","group":"9","constituency":"1","role":"Substitute","begin_date":"2014-07-08","end_date":"9999-12-31"},{"id":12,"representative":"2","group":"10","constituency":"1","role":"Member","begin_date":"2014-07-14","end_date":"9999-12-31"},{"id":13,"representative":"2","group":"11","constituency":"1","role":"Substitute","begin_date":"2015-05-18","end_date":"9999-12-31"},{"id":15,"representative":"2","group":"13","constituency":"1","role":"Member","begin_date":"2014-07-01","end_date":"9999-12-31"},{"id":17,"representative":"2","group":"14","constituency":"3","role":"","begin_date":"2014-07-01","end_date":"9999-12-31"},{"id":2,"representative":"1","group":"2","constituency":"1","role":"Member","begin_date":"2013-10-09","end_date":"2014-06-30"},{"id":16,"representative":"2","group":"13","constituency":"1","role":"Member","begin_date":"2009-07-14","end_date":"2014-06-30"},{"id":18,"representative":"2","group":"14","constituency":"3","role":"","begin_date":"2009-07-14","end_date":"2014-06-30"},{"id":14,"representative":"2","group":"12","constituency":"1","role":"Substitute","begin_date":"2009-09-17","end_date":"2013-01-10"},{"id":11,"representative":"2","group":"8","constituency":"1","role":"Substitute","begin_date":"2009-07-16","end_date":"2012-01-18"},{"id":8,"representative":"1","group":"7","constituency":"1","role":"Member","begin_date":"2006-03-21","end_date":"2009-07-13"},{"id":4,"representative":"1","group":"4","constituency":"1","role":"Member","begin_date":"1999-07-20","end_date":"2004-07-19"},{"id":6,"representative":"1","group":"6","constituency":"2","role":"","begin_date":"1999-07-20","end_date":"2004-07-19"},{"id":1,"representative":"1","group":"1","constituency":"1","role":"Substitute","begin_date":"1997-01-16","end_date":"1999-07-19"},{"id":5,"representative":"1","group":"5","constituency":"1","role":"Member","begin_date":"1996-11-11","end_date":"1999-07-19"},{"id":7,"representative":"1","group":"6","constituency":"2","role":"","begin_date":"1996-11-11","end_date":"1999-07-19"},{"id":3,"representative":"1","group":"3","constituency":"1","role":"Member","begin_date":"1996-11-14","end_date":"1997-01-15"}]
\ No newline at end of file
[{"id":9,"url":"http://testserver/api/mandates/9/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/8/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"2014-07-01","end_date":"9999-12-31"},{"id":10,"url":"http://testserver/api/mandates/10/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/9/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Substitute","begin_date":"2014-07-08","end_date":"9999-12-31"},{"id":12,"url":"http://testserver/api/mandates/12/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/10/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"2014-07-14","end_date":"9999-12-31"},{"id":13,"url":"http://testserver/api/mandates/13/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/11/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Substitute","begin_date":"2015-05-18","end_date":"9999-12-31"},{"id":15,"url":"http://testserver/api/mandates/15/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/13/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"2014-07-01","end_date":"9999-12-31"},{"id":17,"url":"http://testserver/api/mandates/17/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/14/?format=json","constituency":"http://testserver/api/constituencies/3/?format=json","role":"","begin_date":"2014-07-01","end_date":"9999-12-31"},{"id":2,"url":"http://testserver/api/mandates/2/?format=json","representative":"http://testserver/api/representatives/1/?format=json","group":"http://testserver/api/groups/2/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"2013-10-09","end_date":"2014-06-30"},{"id":16,"url":"http://testserver/api/mandates/16/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/13/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"2009-07-14","end_date":"2014-06-30"},{"id":18,"url":"http://testserver/api/mandates/18/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/14/?format=json","constituency":"http://testserver/api/constituencies/3/?format=json","role":"","begin_date":"2009-07-14","end_date":"2014-06-30"},{"id":14,"url":"http://testserver/api/mandates/14/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/12/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Substitute","begin_date":"2009-09-17","end_date":"2013-01-10"},{"id":11,"url":"http://testserver/api/mandates/11/?format=json","representative":"http://testserver/api/representatives/2/?format=json","group":"http://testserver/api/groups/8/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Substitute","begin_date":"2009-07-16","end_date":"2012-01-18"},{"id":8,"url":"http://testserver/api/mandates/8/?format=json","representative":"http://testserver/api/representatives/1/?format=json","group":"http://testserver/api/groups/7/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"2006-03-21","end_date":"2009-07-13"},{"id":4,"url":"http://testserver/api/mandates/4/?format=json","representative":"http://testserver/api/representatives/1/?format=json","group":"http://testserver/api/groups/4/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"1999-07-20","end_date":"2004-07-19"},{"id":6,"url":"http://testserver/api/mandates/6/?format=json","representative":"http://testserver/api/representatives/1/?format=json","group":"http://testserver/api/groups/6/?format=json","constituency":"http://testserver/api/constituencies/2/?format=json","role":"","begin_date":"1999-07-20","end_date":"2004-07-19"},{"id":1,"url":"http://testserver/api/mandates/1/?format=json","representative":"http://testserver/api/representatives/1/?format=json","group":"http://testserver/api/groups/1/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Substitute","begin_date":"1997-01-16","end_date":"1999-07-19"},{"id":5,"url":"http://testserver/api/mandates/5/?format=json","representative":"http://testserver/api/representatives/1/?format=json","group":"http://testserver/api/groups/5/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"1996-11-11","end_date":"1999-07-19"},{"id":7,"url":"http://testserver/api/mandates/7/?format=json","representative":"http://testserver/api/representatives/1/?format=json","group":"http://testserver/api/groups/6/?format=json","constituency":"http://testserver/api/constituencies/2/?format=json","role":"","begin_date":"1996-11-11","end_date":"1999-07-19"},{"id":3,"url":"http://testserver/api/mandates/3/?format=json","representative":"http://testserver/api/representatives/1/?format=json","group":"http://testserver/api/groups/3/?format=json","constituency":"http://testserver/api/constituencies/1/?format=json","role":"Member","begin_date":"1996-11-14","end_date":"1997-01-15"}]
\ No newline at end of file
[{"id":2,"slug":"olle-ludvigsson-1948-10-28","first_name":"Olle","last_name":"LUDVIGSSON","full_name":"Olle LUDVIGSSON","gender":2,"birth_place":"Hälsö","birth_date":"1948-10-28","photo":"http://www.europarl.europa.eu/mepphoto/96673.jpg","active":true,"cv":"","contacts":{"emails":[{"email":"olle.ludvigsson@europarl.europa.eu","kind":"official"}],"phones":[{"number":"+322 28 45442","kind":"office phone"},{"number":"+333 88 1 75442","kind":"office phone"}],"websites":[{"url":"http://www.sap.se/olle","kind":""},{"url":"http://twitter.com/olleludvigsson","kind":"twitter"},{"url":"https://www.facebook.com/olle.ludvigsson","kind":"facebook"},{"url":"http://www.europarl.europa.eu/meps/en/96673/_home.html","kind":"EP"}],"address":[{"country":{"name":"Belgium","code":"BE"},"city":"Brussels","street":"rue Wiertz / Wiertzstraat","number":"60","postcode":"1047","floor":"14G","office_number":"257","kind":"official"},{"country":{"name":"France","code":"FR"},"city":"Strasbourg","street":"Av. du Président Robert Schuman - CS 91024","number":"1","postcode":"67070","floor":"T07","office_number":"070","kind":"official"}]},"url":"http://testserver/api/representatives/2/?format=json"},{"id":1,"slug":"hubert-pirker-1948-10-03","first_name":"Hubert","last_name":"PIRKER","full_name":"Hubert PIRKER","gender":2,"birth_place":"Gries","birth_date":"1948-10-03","photo":"http://www.europarl.europa.eu/mepphoto/2307.jpg","active":false,"cv":"Transport and security spokesman, ÖVP Delegation, European Parliament;\nsecurity spokesman, ÖVP Delegation, European Parliament (2006-2009); security spokesman (coordinator), EPP Group (1999-2004); Deputy Head of ÖVP Delegation, European Parliament (1996-2004);","contacts":{"emails":[],"phones":[],"websites":[{"url":"http://www.europarl.europa.eu/meps/en/2307/_home.html","kind":"EP"}],"address":[]},"url":"http://testserver/api/representatives/1/?format=json"}]
\ No newline at end of file
[{"id":2,"url":"http://testserver/api/representatives/2/?format=json","slug":"olle-ludvigsson-1948-10-28","first_name":"Olle","last_name":"LUDVIGSSON","full_name":"Olle LUDVIGSSON","gender":2,"birth_place":"Hälsö","birth_date":"1948-10-28","photo":"http://www.europarl.europa.eu/mepphoto/96673.jpg","active":true,"cv":"","contacts":{"emails":[{"email":"olle.ludvigsson@europarl.europa.eu","kind":"official"}],"phones":[{"number":"+322 28 45442","kind":"office phone"},{"number":"+333 88 1 75442","kind":"office phone"}],"websites":[{"url":"http://www.sap.se/olle","kind":""},{"url":"http://twitter.com/olleludvigsson","kind":"twitter"},{"url":"https://www.facebook.com/olle.ludvigsson","kind":"facebook"},{"url":"http://www.europarl.europa.eu/meps/en/96673/_home.html","kind":"EP"}],"address":[{"country":{"id":1050,"url":"http://testserver/api/countries/1050/?format=json","name":"Belgium","code":"BE"},"city":"Brussels","street":"rue Wiertz / Wiertzstraat","number":"60","postcode":"1047","floor":"14G","office_number":"257","kind":"official"},{"country":{"id":1095,"url":"http://testserver/api/countries/1095/?format=json","name":"France","code":"FR"},"city":"Strasbourg","street":"Av. du Président Robert Schuman - CS 91024","number":"1","postcode":"67070","floor":"T07","office_number":"070","kind":"official"}]}},{"id":1,"url":"http://testserver/api/representatives/1/?format=json","slug":"hubert-pirker-1948-10-03","first_name":"Hubert","last_name":"PIRKER","full_name":"Hubert PIRKER","gender":2,"birth_place":"Gries","birth_date":"1948-10-03","photo":"http://www.europarl.europa.eu/mepphoto/2307.jpg","active":false,"cv":"Transport and security spokesman, ÖVP Delegation, European Parliament;\nsecurity spokesman, ÖVP Delegation, European Parliament (2006-2009); security spokesman (coordinator), EPP Group (1999-2004); Deputy Head of ÖVP Delegation, European Parliament (1996-2004);","contacts":{"emails":[],"phones":[],"websites":[{"url":"http://www.europarl.europa.eu/meps/en/2307/_home.html","kind":"EP"}],"address":[]}}]
\ No newline at end of file
......@@ -5,18 +5,20 @@ from rest_framework import routers
from representatives.api import (
ChamberViewSet,
ConstituencyViewSet,
CountryViewSet,
GroupViewSet,
MandateViewSet,
RepresentativeViewSet,
)
router = routers.DefaultRouter()
router.register(r'chambers', ChamberViewSet)
router.register(r'constituencies', ConstituencyViewSet)
router.register(r'groups', GroupViewSet)
router.register(r'mandates', MandateViewSet)
router.register(r'representatives', RepresentativeViewSet)
router.register('countries', CountryViewSet, 'api-country')
router.register('chambers', ChamberViewSet, 'api-chamber')
router.register('constituencies', ConstituencyViewSet, 'api-constituency')
router.register('groups', GroupViewSet, 'api-group')
router.register('mandates', MandateViewSet, 'api-mandate')
router.register('representatives', RepresentativeViewSet, 'api-representative')
urlpatterns = [
url(r'api/', include(router.urls)),
url('api/', include(router.urls)),
]
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