Commits

Svyatoslav Bulbakha committed 4b5e526

Accounts

Comments (0)

Files changed (17)

djangoschool/apps/account/__init__.py

Empty file added.

djangoschool/apps/account/admin.py

+from django.contrib import admin
+from django.contrib.auth.models import User
+from django.contrib.auth.admin import UserAdmin
+
+from .models import UserProfile
+
+
+class UserProfileInline(admin.TabularInline):
+    model = UserProfile
+
+
+class CustomUserAdmin(UserAdmin):
+    inlines = UserAdmin.inlines + [UserProfileInline]
+
+
+admin.site.unregister(User)
+admin.site.register(User, CustomUserAdmin)

djangoschool/apps/account/migrations/0001_initial.py

+# -*- coding: utf-8 -*-
+import 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 'UserProfile'
+        db.create_table('account_userprofile', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('mugshot', self.gf('django.db.models.fields.files.ImageField')(max_length=100, blank=True)),
+            ('privacy', self.gf('django.db.models.fields.CharField')(default='registered', max_length=15)),
+            ('user', self.gf('django.db.models.fields.related.OneToOneField')(related_name='my_profile', unique=True, to=orm['auth.User'])),
+            ('about', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
+        ))
+        db.send_create_signal('account', ['UserProfile'])
+
+    def backwards(self, orm):
+        # Deleting model 'UserProfile'
+        db.delete_table('account_userprofile')
+
+    models = {
+        'account.userprofile': {
+            'Meta': {'object_name': 'UserProfile'},
+            'about': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            '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': "'my_profile'", 'unique': 'True', 'to': "orm['auth.User']"})
+        },
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        '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'}),
+            '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'})
+        }
+    }
+
+    complete_apps = ['account']

djangoschool/apps/account/migrations/__init__.py

Empty file added.

djangoschool/apps/account/models.py

+from django.db import models
+from django.contrib.auth.models import User
+from django.utils.translation import ugettext_lazy as _
+
+from userena.models import UserenaBaseProfile
+
+
+class UserProfile(UserenaBaseProfile):
+    user = models.OneToOneField(User,
+                                unique=True,
+                                verbose_name=_('user'),
+                                related_name='my_profile')
+    about = models.TextField(_('about'), null=True, blank=True)
+
+    class Meta:
+        verbose_name = _('profile')
+        verbose_name_plural = _('profiles')
+
+    def __unicode__(self):
+        return '%s profile' % self.user.username

djangoschool/apps/account/tests.py

+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.assertEqual(1 + 1, 2)

djangoschool/apps/account/views.py

+# Create your views here.

djangoschool/apps/core/migrations/0003_auto__add_field_entry__content_rendered__chg_field_entry_content.py

+# -*- coding: utf-8 -*-
+import 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 'Entry._content_rendered'
+        db.add_column('core_entry', '_content_rendered',
+                      self.gf('django.db.models.fields.TextField')(default='', blank=True),
+                      keep_default=False)
+
+
+        # Changing field 'Entry.content'
+        db.alter_column('core_entry', 'content', self.gf('markitup.fields.MarkupField')(no_rendered_field=True))
+    def backwards(self, orm):
+        # Deleting field 'Entry._content_rendered'
+        db.delete_column('core_entry', '_content_rendered')
+
+
+        # Changing field 'Entry.content'
+        db.alter_column('core_entry', 'content', self.gf('django.db.models.fields.TextField')())
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        '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'}),
+            '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'})
+        },
+        'core.comment': {
+            'Meta': {'object_name': 'Comment'},
+            'content': ('django.db.models.fields.TextField', [], {}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'entry': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Entry']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        },
+        'core.entry': {
+            'Meta': {'object_name': 'Entry'},
+            '_content_rendered': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'content': ('markitup.fields.MarkupField', [], {'no_rendered_field': 'True'}),
+            'content_short': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+        }
+    }
+
+    complete_apps = ['core']

djangoschool/apps/core/models.py

 from django.contrib.auth.models import User
 from django.utils.translation import ugettext_lazy as _
 
+from markitup.fields import MarkupField
+
 
 class Entry(models.Model):
     title = models.CharField(_('title'), max_length=200)
-    content = models.TextField(_('content'))
+    content = MarkupField(_('content'))
     content_short = models.TextField(_('short content'), null=True,
             blank=True)
     user = models.ForeignKey(User, verbose_name=_('user'))

djangoschool/apps/core/views.py

 from django.shortcuts import render, get_object_or_404, redirect
+from django.contrib.auth.decorators import login_required
 
 from .models import Entry
 from .forms import EntryForm
     })
 
 
+@login_required
 def entry_add(request):
     form = EntryForm(request.POST or None)
 
     })
 
 
+@login_required
 def entry_edit(request, entry_id):
     entry = get_object_or_404(Entry, pk=entry_id, user=request.user)
     form = EntryForm(request.POST or None, instance=entry)

djangoschool/settings.py

     'django.core.context_processors.request',
 )
 
+AUTHENTICATION_BACKENDS = (
+    'userena.backends.UserenaAuthenticationBackend',
+    'guardian.backends.ObjectPermissionBackend',
+    'django.contrib.auth.backends.ModelBackend',
+)
+
 ROOT_URLCONF = 'djangoschool.urls'
 
 # Python dotted path to the WSGI application used by Django's runserver.
     # 'django.contrib.admindocs',
     'south',
     'crispy_forms',
+    'markitup',
+    'userena',
+    'guardian',
+    'easy_thumbnails',
 
     'core',
+    'account',
 )
 
 # A sample logging configuration. The only tangible logging
     }
 }
 
+EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
+EMAIL_FILE_PATH = os.path.join(PROJECT_ROOT, '..', 'emails')
+
 CRISPY_TEMPLATE_PACK = 'uni_form'
+
+MARKITUP_FILTER = ('markdown.markdown', {'safe_mode': True})
+MARKITUP_SET = 'markitup/sets/markdown'
+
+LOGIN_REDIRECT_URL = '/accounts/%(username)s/'
+LOGIN_URL = '/accounts/signin/'
+LOGOUT_URL = '/accounts/signout/'
+
+ANONYMOUS_USER_ID = -1
+AUTH_PROFILE_MODULE = 'account.UserProfile'

djangoschool/templates/base.html

         <script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>
         <script type="text/javascript" src="{% static 'js/uni-form.jquery.min.js' %}"></script>
         <script type="text/javascript" src="{% static 'js/application.js' %}"></script>
+        {% block extra_head %}{% endblock %}
     </head>
     <body>
         <div class="header container_12">
             <div class="grid_6 umenu">
                 {% if request.user.is_authenticated %}
                     <a href="{% url core_entry_add %}">{% trans "Add entry" %}</a>
-                    <a href="#">{% trans "Logout" %}</a>
+                    <a href="{% url userena_signout %}">{% trans "Logout" %}</a>
                 {% else %}
-                    <form action="" method="post">{% csrf_token %}
-                        <input type="text" name="username" placeholder="{% trans "Username" %}" />
+                <form action="{% url userena_signin %}" method="post">{% csrf_token %}
+                        <input type="text" name="identification" placeholder="{% trans "Username" %}" />
                         <input type="password" name="password" placeholder="{% trans "Password" %}" />
                         <input type="submit" value="{% trans "Login" %}" />
                     </form>
-                    <a href="#">{% trans "Registration" %}</a>
+                    <a href="{% url userena_signup %}">{% trans "Registration" %}</a>
                 {% endif %}
             </div>
             <div class="clear"></div>

djangoschool/templates/core/entry_add.html

 {% extends "base.html" %}
 
 {% load i18n %}
+{% load markitup_tags %}
+
+{% block extra_head %}{% markitup_media %}{% endblock %}
 
 {% block title %}{% trans 'Add entry' %}{% endblock %}
 
         <input type="submit" value="{% trans 'Add' %}" class="primaryAction" />
     </div>
 </form>
+
+{% markitup_editor form.content.auto_id %}
 {% endblock %}

djangoschool/templates/core/entry_detail.html

 {% block title %}{{ entry.title }}{% endblock %}
 
 {% block content %}
-<a href="{% url core_entry_edit entry.pk %}" class="edit_link">{% trans 'Edit' %}</a>
+{% if request.user == entry.user %}
+    <a href="{% url core_entry_edit entry.pk %}" class="edit_link">{% trans 'Edit' %}</a>
+{% endif %}
+
 <h2 class="entry_detail">{{ entry.title }}</h2>
 <p class="metainfo">{{ entry.created }}</p>
 {{ entry.content|linebreaks }}

djangoschool/templates/core/entry_edit.html

 {% extends "base.html" %}
 
 {% load i18n %}
+{% load markitup_tags %}
+
+{% block extra_head %}{% markitup_media %}{% endblock %}
 
 {% block title %}{% trans 'Edit entry' %}{% endblock %}
 
         <input type="submit" value="{% trans 'Save' %}" class="primaryAction" />
     </div>
 </form>
+
+{% markitup_editor form.content.auto_id %}
 {% endblock %}
 
     # Uncomment the next line to enable the admin:
     url(r'^admin/', include(admin.site.urls)),
+    url(r'^markitup/', include('markitup.urls')),
+    url(r'^accounts/', include('userena.urls')),
 )
 django
 south
 -e git+https://github.com/maraujop/django-crispy-forms.git#egg=django-crispy-forms
+django-markitup
+markdown
+django-userena
+PIL