Commits

Andy Mikhailenko  committed 98cf662

Rearranged stuff.

  • Participants
  • Parent commits 9351f8d

Comments (0)

Files changed (21)

File depts/departments/admin.py

 
 
 class EmployeeAdmin(admin.ModelAdmin):
+    list_display = ('position', 'person', 'department', 'publish')
+    list_editable = ('publish',)
     ordering = ('person__last_name',)
-    filter_horizontal = ('courses',)
+    #filter_horizontal = ('courses',)
 
 
 class PositionAdmin(admin.ModelAdmin):

File depts/departments/migrations/0001_initial.py

+# -*- coding: utf-8 -*-
+
+from south.db import db
+from django.db import models
+from departments.models import *
+
+class Migration:
+    
+    def forwards(self, orm):
+        
+        # Adding model 'Department'
+        db.create_table('departments_department', (
+            ('id', orm['departments.Department:id']),
+            ('upd_date', orm['departments.Department:upd_date']),
+            ('pub_date', orm['departments.Department:pub_date']),
+            ('title', orm['departments.Department:title']),
+            ('slug', orm['departments.Department:slug']),
+            ('description', orm['departments.Department:description']),
+            ('activity', orm['departments.Department:activity']),
+            ('history', orm['departments.Department:history']),
+        ))
+        db.send_create_signal('departments', ['Department'])
+        
+        # Adding model 'Position'
+        db.create_table('departments_position', (
+            ('id', orm['departments.Position:id']),
+            ('title', orm['departments.Position:title']),
+            ('title_plural', orm['departments.Position:title_plural']),
+            ('weight', orm['departments.Position:weight']),
+        ))
+        db.send_create_signal('departments', ['Position'])
+        
+        # Adding model 'Employee'
+        db.create_table('departments_employee', (
+            ('id', orm['departments.Employee:id']),
+            ('upd_date', orm['departments.Employee:upd_date']),
+            ('pub_date', orm['departments.Employee:pub_date']),
+            ('person', orm['departments.Employee:person']),
+            ('department', orm['departments.Employee:department']),
+            ('position', orm['departments.Employee:position']),
+            ('publish', orm['departments.Employee:publish']),
+        ))
+        db.send_create_signal('departments', ['Employee'])
+        
+    
+    
+    def backwards(self, orm):
+        
+        # Deleting model 'Department'
+        db.delete_table('departments_department')
+        
+        # Deleting model 'Position'
+        db.delete_table('departments_position')
+        
+        # Deleting model 'Employee'
+        db.delete_table('departments_employee')
+        
+    
+    
+    models = {
+        'auth.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']", 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'unique_together': "(('content_type', 'codename'),)"},
+            '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': {
+            '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']", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            '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']", 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'unique_together': "(('app_label', 'model'),)", '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'})
+        },
+        'departments.department': {
+            'activity': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'history': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'slug': ('autoslug.fields.AutoSlugField', [], {'unique_with': '()', 'max_length': '50', 'blank': 'True', 'unique': 'True', 'populate_from': 'None', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '250'}),
+            'upd_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+        },
+        'departments.employee': {
+            'department': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'staff'", 'to': "orm['departments.Department']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'positions'", 'to': "orm['scholars.Scholar']"}),
+            'position': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'staff'", 'null': 'True', 'to': "orm['departments.Position']"}),
+            'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+            'upd_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'})
+        },
+        'departments.position': {
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
+            'title_plural': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
+            'weight': ('django.db.models.fields.IntegerField', [], {'default': '10'})
+        },
+        'scholars.scholar': {
+            'Meta': {'unique_together': "(('first_name', 'last_name'),)"},
+            'academic_degree': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}),
+            'academic_field': ('django.db.models.fields.IntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}),
+            'academic_title': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}),
+            'consulting_schedule': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'consulting_topics': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+            'honor_title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+            'mid_name': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}),
+            'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'publications': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'slug': ('autoslug.fields.AutoSlugField', [], {'unique_with': '()', 'max_length': '50', 'blank': 'True', 'unique': 'True', 'populate_from': 'None', 'db_index': 'True'}),
+            'upd_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
+        }
+    }
+    
+    complete_apps = ['departments']

File depts/departments/migrations/__init__.py

Empty file added.

File depts/departments/models.py

 
 # 3rd-party
 from base.models import NamedModel, TrackedModel
-from courses.models import Course
-from scholars.models import Scholar
+from depts.scholars.models import Scholar
 
 
 # NOTE: dean's office should be a separate set of models (maybe app).
         return reverse('departments-dept-detail', kwargs={'slug': self.slug})
 
     def get_courses(self):
-        return Course.objects.filter(lecturers__in=self.staff.all())
+        # FIXME   return Course.objects.filter(lecturers__in=self.staff.all())
+        return []
 
 
 class Position(Model):
                           blank=True, null=True, related_name='staff')
 
     # what does this employee actually do:
-    courses = ManyToManyField(Course, verbose_name=_('courses'), blank=True,
-                              related_name='lecturers')
+    #courses = ManyToManyField(Course, verbose_name=_('courses'), blank=True,
+    #                          related_name='lecturers')
     publish = BooleanField(_('publish'), default=True,
                            help_text=_('display this position on the site?'))
 

File depts/departments/templates/department_detail.html

-{% extends "base.html" %}
-
-{% load wiki pytils_numeral %}
-
-{% block title %}{{ object.title }}{% endblock %}
-
-{% block content %}
-    {{ object.description|render_wiki }}
-    {% if object.staff.count %}
-        <h2>Состав ({{ object.staff.count|get_plural:"человек,человека,человек"|capfirst }})</h2>
-        <dl>
-        {% for position, people in staff %}
-            <dt>{{ position|capfirst }}</dt>
-            {% for employee in people %}
-                <dd><a href="{{ employee.person.get_absolute_url }}">{{ employee.person }}</a>
-                    {% if employee.person.degree %}&mdash; {{ employee.person.degree }}{% endif %}</dd>
-            {% endfor %}
-        {% endfor %}
-        </dl>
-    {% endif %}
-
-    {% if object.get_courses.count %}
-        <h2>Читаемые курсы</h2>
-        <p>
-        {% for course in object.get_courses %}
-            <a href="{{ course.get_absolute_url }}">{{ course }}</a>{% if not forloop.last %},{% endif %}
-        {% endfor %}
-        </p>
-    {% endif %}
-
-    {% if object.activity %}
-        <h2>Деятельность</h2>
-        {{ object.activity|render_wiki }}
-    {% endif %}
-
-    {% if object.history %}
-        <h2>История</h2>
-        {{ object.history|render_wiki }}
-    {% endif %}
-
-{% endblock %}

File depts/departments/templates/department_list.html

-{% extends "base.html" %}
-
-{% block title %}Структура{% endblock %}
-
-{% block content %}
-    <ul>
-    {% for object in object_list %}
-        <li><a href="{{ object.get_absolute_url }}">{{ object|capfirst }}</a></li>
-    {% endfor %}
-    </ul>
-{% endblock %}

File depts/departments/templates/departments/department_detail.html

+{% extends "base.html" %}
+
+{% load wiki pytils_numeral %}
+
+{% block title %}{{ object.title }}{% endblock %}
+
+{% block content %}
+    {{ object.description|render_wiki }}
+    {% if object.staff.count %}
+        <h2>Состав ({{ object.staff.count|get_plural:"человек,человека,человек"|capfirst }})</h2>
+        <dl>
+        {% for position, people in staff %}
+            <dt>{{ position|capfirst }}</dt>
+            {% for employee in people %}
+                <dd><a href="{{ employee.person.get_absolute_url }}">{{ employee.person }}</a>
+                    {% if employee.person.degree %}&mdash; {{ employee.person.degree }}{% endif %}</dd>
+            {% endfor %}
+        {% endfor %}
+        </dl>
+    {% endif %}
+
+    {% if object.get_courses.count %}
+        <h2>Читаемые курсы</h2>
+        <p>
+        {% for course in object.get_courses %}
+            <a href="{{ course.get_absolute_url }}">{{ course }}</a>{% if not forloop.last %},{% endif %}
+        {% endfor %}
+        </p>
+    {% endif %}
+
+    {% if object.activity %}
+        <h2>Деятельность</h2>
+        {{ object.activity|render_wiki }}
+    {% endif %}
+
+    {% if object.history %}
+        <h2>История</h2>
+        {{ object.history|render_wiki }}
+    {% endif %}
+
+{% endblock %}

File depts/departments/templates/departments/department_list.html

+{% extends "base.html" %}
+
+{% block title %}Структура{% endblock %}
+
+{% block content %}
+    <ul>
+    {% for object in object_list %}
+        <li><a href="{{ object.get_absolute_url }}">{{ object|capfirst }}</a></li>
+    {% endfor %}
+    </ul>
+{% endblock %}

File depts/departments/urls.py

 from django.conf.urls.defaults import *
 
 
-urlpatterns = patterns('departments.views',
+urlpatterns = patterns('depts.departments.views',
     url(r'^$',
         view='department_list',
         name='departments-dept-list'),

File depts/departments/views.py

 from models import Department, Employee, Position
 
 
-@render_to()
+@render_to('departments/department_list.html')
 def department_list(request):
     qs = Department.objects.all()
     return {'object_list': qs}
 
 _get_dept = lambda slug: get_object_or_404(Department, slug=slug)
 
-@render_to()
+@render_to('departments/department_detail.html')
 def department_detail(request, slug):
     obj = _get_dept(slug)
 

File depts/scholars/admin.py

 from django.contrib import admin
 
 # 3rd-party
-from departments.models import Employee
+from depts.departments.models import Employee
 
 # this app
 from models import Scholar

File depts/scholars/migrations/0001_initial.py

+# -*- coding: utf-8 -*-
+
+from south.db import db
+from django.db import models
+from scholars.models import *
+
+class Migration:
+    
+    def forwards(self, orm):
+        
+        # Adding model 'Scholar'
+        db.create_table('scholars_scholar', (
+            ('id', orm['scholars.Scholar:id']),
+            ('upd_date', orm['scholars.Scholar:upd_date']),
+            ('pub_date', orm['scholars.Scholar:pub_date']),
+            ('first_name', orm['scholars.Scholar:first_name']),
+            ('mid_name', orm['scholars.Scholar:mid_name']),
+            ('last_name', orm['scholars.Scholar:last_name']),
+            ('slug', orm['scholars.Scholar:slug']),
+            ('academic_degree', orm['scholars.Scholar:academic_degree']),
+            ('academic_field', orm['scholars.Scholar:academic_field']),
+            ('academic_title', orm['scholars.Scholar:academic_title']),
+            ('honor_title', orm['scholars.Scholar:honor_title']),
+            ('publications', orm['scholars.Scholar:publications']),
+            ('consulting_schedule', orm['scholars.Scholar:consulting_schedule']),
+            ('consulting_topics', orm['scholars.Scholar:consulting_topics']),
+            ('email', orm['scholars.Scholar:email']),
+            ('user', orm['scholars.Scholar:user']),
+        ))
+        db.send_create_signal('scholars', ['Scholar'])
+        
+        # Creating unique_together for [first_name, last_name] on Scholar.
+        db.create_unique('scholars_scholar', ['first_name', 'last_name'])
+        
+    
+    
+    def backwards(self, orm):
+        
+        # Deleting unique_together for [first_name, last_name] on Scholar.
+        db.delete_unique('scholars_scholar', ['first_name', 'last_name'])
+        
+        # Deleting model 'Scholar'
+        db.delete_table('scholars_scholar')
+        
+    
+    
+    models = {
+        'auth.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']", 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'unique_together': "(('content_type', 'codename'),)"},
+            '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': {
+            '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']", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+            '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']", 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'unique_together': "(('app_label', 'model'),)", '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'})
+        },
+        'scholars.scholar': {
+            'Meta': {'unique_together': "(('first_name', 'last_name'),)"},
+            'academic_degree': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}),
+            'academic_field': ('django.db.models.fields.IntegerField', [], {'max_length': '1', 'null': 'True', 'blank': 'True'}),
+            'academic_title': ('django.db.models.fields.CharField', [], {'max_length': '1', 'blank': 'True'}),
+            'consulting_schedule': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'consulting_topics': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+            'honor_title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+            'mid_name': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}),
+            'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'publications': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'slug': ('autoslug.fields.AutoSlugField', [], {'unique_with': '()', 'max_length': '50', 'blank': 'True', 'unique': 'True', 'populate_from': 'None', 'db_index': 'True'}),
+            'upd_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
+        }
+    }
+    
+    complete_apps = ['scholars']

File depts/scholars/migrations/__init__.py

Empty file added.

File depts/scholars/models.py

 # django
 from django.contrib.auth.models import User
 from django.core.urlresolvers import reverse
-from django.db.models import (CharField, EmailField, IntegerField, OneToOneField,
-                              TextField)
+from django.db.models import (CharField, EmailField, ForeignKey, IntegerField,
+                              OneToOneField, TextField)
 from django.utils.translation import ugettext_lazy as _
 
 # 3rd-party

File depts/scholars/templates/scholar_detail.html

-{% extends "base.html" %}
-
-{% load wiki pytils_numeral account_tags %}
-
-{% block title %}{{ object }}{% endblock %}
-
-{% block content %}
-    <div class="vcard">
-    <span class="fn" style="display:none;">{{ object }}</span> {#<!-- can't wrap heading in vcard block; add base template hooks? -->#}
-    
-    <p class="title">{{ object.get_academic_props|capfirst }}</p>
-
-    {% if object.positions.active.count %}
-        <!--<h2>Должности</h2>-->
-        <ul>
-        {% for position in object.positions.active %}
-            <li>{{ position.get_position }} &mdash;
-                <span class="org vcard"><a href="{{ position.department.get_absolute_url }}" class="url fn org" rel="group">{{ position.department }}</a></span></li>
-        {% endfor %}
-        </ul>
-    {% else %}
-        <p>В данный момент не преподает.</p>
-    {% endif %}
-
-    {% if object.user or object.get_email %}
-        <h2>Контактная информация</h2>
-
-        {% if object.user %}<p>См. <a href="{% url users-detail object.user.username %}">карточку пользователя</a></p>{% endif %}
-        {% if object.user and object.user.contacts.count %}
-            {% get_contacts_for object.user %}
-        {% else %}
-            <p>E-mail: <a href="mailto:{{ object.get_email }}" class="email">{{ object.get_email }}</a></p>
-        {% endif %}
-    {% endif %}
-
-    {% if courses %}
-        <h2>Преподает</h2>
-        <ul>
-        {% for course in courses %}
-            <li><a href="{{ course.get_absolute_url }}">{{ course }}</a></li>
-        {% endfor %}
-        </ul>
-    {% endif %}
-
-    {% if object.consulting_schedule %}
-        <h2>Консультации</h2>
-        <p>{{ object.consulting_schedule }}</p>
-    {% endif %}
-
-    {% if object.consulting_topics %}
-        <h2>Темы для курсовых и дипломных работ</h2>
-        {{ object.consulting_topics|render_wiki }}
-    {% endif %}
-
-    {% if object.publications %}
-        <h2>Научные публикации</h2>
-        {{ object.publications|render_wiki }}
-    {% endif %}
-    </div>
-{% endblock %}

File depts/scholars/templates/scholar_list.html

-{% extends "base.html" %}
-
-{% block title %}Исследователи{% endblock %}
-
-{% block content %}
-    <ul>
-    {% for object in object_list %}
-        <li><a href="{{ object.get_absolute_url }}"><strong>{{ object.last_name }}</strong>
-            {{ object.first_name }} {{ object.mid_name }}</a></li>
-    {% endfor %}
-    </ul>
-{% endblock %}

File depts/scholars/templates/scholars/scholar_detail.html

+{% extends "base.html" %}
+
+{% load wiki pytils_numeral %}
+
+{% block title %}{{ object }}{% endblock %}
+
+{% block content %}
+    <div class="vcard">
+    <span class="fn" style="display:none;">{{ object }}</span> {#<!-- can't wrap heading in vcard block; add base template hooks? -->#}
+
+    <p class="title">{{ object.get_academic_props|capfirst }}</p>
+
+    {% if object.positions.active.count %}
+        <!--<h2>Должности</h2>-->
+        <ul>
+        {% for position in object.positions.active %}
+            <li>{{ position.get_position }} &mdash;
+                <span class="org vcard"><a href="{{ position.department.get_absolute_url }}" class="url fn org" rel="group">{{ position.department }}</a></span></li>
+        {% endfor %}
+        </ul>
+    {% else %}
+        <p>В данный момент не преподает.</p>
+    {% endif %}
+
+    {% if object.user or object.get_email %}
+        <h2>Контактная информация</h2>
+
+        {% if object.user %}<p>См. <a href="{% url users-detail object.user.username %}">карточку пользователя</a></p>{% endif %}
+        <p>E-mail: <a href="mailto:{{ object.get_email }}" class="email">{{ object.get_email }}</a></p>
+    {% endif %}
+
+    {% if courses %}
+        <h2>Преподает</h2>
+        <ul>
+        {% for course in courses %}
+            <li><a href="{{ course.get_absolute_url }}">{{ course }}</a></li>
+        {% endfor %}
+        </ul>
+    {% endif %}
+
+    {% if object.consulting_schedule %}
+        <h2>Консультации</h2>
+        <p>{{ object.consulting_schedule }}</p>
+    {% endif %}
+
+    {% if object.consulting_topics %}
+        <h2>Темы для курсовых и дипломных работ</h2>
+        {{ object.consulting_topics|render_wiki }}
+    {% endif %}
+
+    {% if object.publications %}
+        <h2>Научные публикации</h2>
+        {{ object.publications|render_wiki }}
+    {% endif %}
+    </div>
+{% endblock %}

File depts/scholars/templates/scholars/scholar_list.html

+{% extends "base.html" %}
+
+{% block title %}Исследователи{% endblock %}
+
+{% block content %}
+    <ul>
+    {% for object in object_list %}
+        <li><a href="{{ object.get_absolute_url }}"><strong>{{ object.last_name }}</strong>
+            {{ object.first_name }} {{ object.mid_name }}</a></li>
+    {% endfor %}
+    </ul>
+{% endblock %}

File depts/scholars/urls.py

 
 from django.conf.urls.defaults import *
 
-urlpatterns = patterns('scholars.views',
+urlpatterns = patterns('depts.scholars.views',
     url(r'^$',
         view='scholar_list',
         name='scholars-scholar-list'),

File depts/scholars/views.py

 from django.utils.translation import ugettext as _
 
 # 3rd-party
-from courses.models import Course
+try:
+    from courses.models import Course
+except ImportError:
+    Course = None
 from view_shortcuts.decorators import render_to
 
 # this app
 from models import Scholar
 
 
-@render_to()
+@render_to('scholars/scholar_list.html')
 def scholar_list(request):
     qs = Scholar.objects.all()
     return {'object_list': qs}
 
 _get_scholar = lambda slug: get_object_or_404(Scholar, slug=slug)
 
-@render_to()
+@render_to('scholars/scholar_detail.html')
 def scholar_detail(request, slug):
     obj = _get_scholar(slug)
-    courses = Course.objects.filter(lecturers__person=obj)
+    if Course is not None:
+        courses = Course.objects.filter(lecturers__person=obj)
+    else:
+        courses = None
     return {'object': obj, 'courses': courses}
 scholar_detail.navigation = lambda request, slug: unicode(_get_scholar(slug))
     version  = '0.1',
     packages = ['depts'],
 
-    requires = ['python (>= 2.4)', 'django (>= 1.0)', 'autoslug (>= 1.3)'],
-    extras_require = {'cyrillic': 'pytils >= 0.2'},
+    requires = [
+        'python (>= 2.4)',
+        'django (>= 1.0)',
+        'autoslug (>= 1.3)',
+    ],
+    extras_require = {
+        'south': 'south (>= 0.6.2)',
+        'cyrillic': 'pytils >= 0.2'
+    },
 
     description  = 'a way to describe an organization and its employees',
     long_description = readme,