Skip to content

Feature/megafon #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion accounts/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- encoding: utf-8 -*-
import json

from django.db.models import Count
from django.conf.urls import url
from django.contrib.auth.models import User, Group
from django.contrib.auth import authenticate, logout
Expand Down Expand Up @@ -30,7 +31,7 @@ class Meta:
resource_name = 'account/user'
authentication = Authentication()
authorization = Authorization()
fields = ['id', 'username', 'first_name', 'last_name', 'groups', 'email']
fields = ['id', 'username', 'first_name', 'last_name', 'groups', 'email', 'date_joined']
filtering = {
"id" : ['exact',],
"username": ALL_WITH_RELATIONS,
Expand Down Expand Up @@ -211,6 +212,7 @@ class Meta:
filtering = {
"object_id" : ['exact', ],
"content_type" : ['exact', ],
"level" : ['exact', ],
"profile" : ALL_WITH_RELATIONS,

}
Expand All @@ -221,6 +223,9 @@ def prepend_urls(self):
url(r"^(?P<resource_name>%s)/(?P<content_type>\w+?)/(?P<object_id>\d+?)%s$" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('dispatch_list'),
name="api_dispatch_list"),
url(r"^(?P<resource_name>%s)/(?P<content_type>\w+?)/best%s$" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('get_best_linked_profiles'),
name="api_best_linked_profiles"),
]

def dispatch_list(self, request, **kwargs):
Expand Down Expand Up @@ -250,3 +255,27 @@ def dispatch_list(self, request, **kwargs):
location=self.get_resource_uri(bundle))

return ModelResource.dispatch_list(self, request, **kwargs)

def get_best_linked_profiles(self, request, **kwargs):
self.method_check(request, allowed=['get'])
self.is_authenticated(request)
self.throttle_check(request)

if 'content_type' in kwargs:
levels = []
if 'level' in request.GET:
levels = [int(lvl) for lvl in request.GET.getlist('level')]

profiles = Profile.objects.filter(id__gt=1,
objectprofilelink__content_type__model=kwargs["content_type"],
objectprofilelink__level__in=levels).annotate(num_post=Count('objectprofilelink')).order_by('-num_post')

bundles = []
for obj in profiles:
profile_resource = ProfileResource()
bundle = profile_resource.build_bundle(obj=obj, request=request)
bundles.append(profile_resource.full_dehydrate(bundle, for_list=True))

return self.create_response(request, {'objects' : bundles})

return ModelResource.dispatch_list(self, request, **kwargs)
2 changes: 1 addition & 1 deletion accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ObjectProfileLink(models.Model):

@receiver(post_save, sender=User)
def create_profile_on_user_signup(sender, created, instance, **kwargs):
if created:
if created and not instance.is_superuser:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ça me semble OK, mais je me demande juste ce qui rend cet ajout nécessaire ?

profile_model = get_profile_model()
profile_model.objects.create(user=instance)

Expand Down
Empty file added megafon/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions megafon/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.contrib import admin
from mptt.admin import MPTTModelAdmin
from .models import Post

admin.site.register(Post, MPTTModelAdmin)
81 changes: 81 additions & 0 deletions megafon/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from django.conf.urls import *

from tastypie.resources import ModelResource
from tastypie import fields

from .models import Post
from accounts.models import Profile

from graffiti.api import TaggedItemResource
from dataserver.authentication import AnonymousApiKeyAuthentication
from tastypie.authorization import DjangoAuthorization
from tastypie.constants import ALL_WITH_RELATIONS
from tastypie.utils import trailing_slash

from accounts.api import ProfileResource


class PostResource(ModelResource):

""" A post resource """

tags = fields.ToManyField(TaggedItemResource, 'tagged_items', full=True, null=True)
parent = fields.OneToOneField("megafon.api.PostResource", 'parent', null=True)


class Meta:
queryset = Post.objects.all()
resource_name = 'megafon/post'
allowed_methods = ['get', 'post']
always_return_data = True
authentication = AnonymousApiKeyAuthentication()
authorization = DjangoAuthorization()

filtering = {
"slug": ('exact',),
"id": ('exact',),
"level" : ('exact', ),
"answers_count" : ('exact', ),
}
ordering = ['updated_on', 'answers_count']

def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/questions%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_questions'), name="api_get_questions"),
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/answers%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_answers'), name="api_get_answers"),
url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)/root%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_root'), name="api_get_root"),
]

def get_questions(self, request, **kwargs):
kwargs['level'] = 0
return self.get_list(request, **kwargs)


def get_answers(self, request, **kwargs):
self.method_check(request, allowed=['get'])
self.is_authenticated(request)
self.throttle_check(request)

post = self.get_object_list(request).get(id=kwargs['pk'])
answers = post.get_children().order_by('-updated_on')

bundles = []
for obj in answers:
bundle = self.build_bundle(obj=obj, request=request)
bundles.append(self.full_dehydrate(bundle, for_list=True))

return self.create_response(request, {'objects' : bundles})

def get_root(self, request, **kwargs):
self.method_check(request, allowed=['get'])
self.is_authenticated(request)
self.throttle_check(request)

try :
post = self.get_object_list(request).get(id=kwargs['pk']).get_root()
bundle = self.build_bundle(obj=post, request=request)
return self.create_response(request, self.full_dehydrate(bundle))
except:
pass

return self.create_response(request, {})
93 changes: 93 additions & 0 deletions megafon/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'Post'
db.create_table(u'megafon_post', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length='200', blank=True)),
('posted_on', self.gf('django.db.models.fields.DateField')(auto_now_add=True, blank=True)),
('author', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['accounts.Profile'])),
('text', self.gf('django.db.models.fields.TextField')()),
('slug', self.gf('autoslug.fields.AutoSlugField')(unique_with=('id',), max_length=50, populate_from=None)),
('parent', self.gf('mptt.fields.TreeForeignKey')(blank=True, related_name='answers', null=True, to=orm['megafon.Post'])),
(u'lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
(u'level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)),
))
db.send_create_signal(u'megafon', ['Post'])


def backwards(self, orm):
# Deleting model 'Post'
db.delete_table(u'megafon_post')


models = {
u'accounts.profile': {
'Meta': {'object_name': 'Profile'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mugshot': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'privacy': ('django.db.models.fields.CharField', [], {'default': "'registered'", 'max_length': '15'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': u"orm['auth.User']"})
},
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'megafon.post': {
'Meta': {'object_name': 'Post'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['accounts.Profile']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
u'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
u'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'answers'", 'null': 'True', 'to': u"orm['megafon.Post']"}),
'posted_on': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'slug': ('autoslug.fields.AutoSlugField', [], {'unique_with': "('id',)", 'max_length': '50', 'populate_from': 'None'}),
'text': ('django.db.models.fields.TextField', [], {}),
'title': ('django.db.models.fields.CharField', [], {'max_length': "'200'", 'blank': 'True'}),
u'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
}
}

complete_apps = ['megafon']
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding field 'Post.updated_on'
db.add_column(u'megafon_post', 'updated_on',
self.gf('django.db.models.fields.DateTimeField')(auto_now=True, auto_now_add=True, default=datetime.datetime(2015, 5, 28, 0, 0), blank=True),
keep_default=False)

# Adding field 'Post.answers_count'
db.add_column(u'megafon_post', 'answers_count',
self.gf('django.db.models.fields.PositiveIntegerField')(default=0),
keep_default=False)


# Changing field 'Post.posted_on'
db.alter_column(u'megafon_post', 'posted_on', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))

def backwards(self, orm):
# Deleting field 'Post.updated_on'
db.delete_column(u'megafon_post', 'updated_on')

# Deleting field 'Post.answers_count'
db.delete_column(u'megafon_post', 'answers_count')


# Changing field 'Post.posted_on'
db.alter_column(u'megafon_post', 'posted_on', self.gf('django.db.models.fields.DateField')(auto_now_add=True))

models = {
u'accounts.profile': {
'Meta': {'object_name': 'Profile'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'mugshot': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}),
'privacy': ('django.db.models.fields.CharField', [], {'default': "'registered'", 'max_length': '15'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': u"orm['auth.User']"})
},
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'megafon.post': {
'Meta': {'object_name': 'Post'},
'answers_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['accounts.Profile']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
u'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
u'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'parent': ('mptt.fields.TreeForeignKey', [], {'blank': 'True', 'related_name': "'answers'", 'null': 'True', 'to': u"orm['megafon.Post']"}),
'posted_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'slug': ('autoslug.fields.AutoSlugField', [], {'unique_with': "('id',)", 'max_length': '50', 'populate_from': 'None'}),
'text': ('django.db.models.fields.TextField', [], {}),
'title': ('django.db.models.fields.CharField', [], {'max_length': "'200'", 'blank': 'True'}),
u'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
'updated_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'auto_now_add': 'True', 'blank': 'True'})
}
}

complete_apps = ['megafon']
Loading