Commit a3ac522a authored by Sofia Papagiannaki's avatar Sofia Papagiannaki

Progress VI

parent 612c385e
[
{
"model": "im.memberrejectpolicy",
"model": "im.memberleavepolicy",
"pk": 1,
"fields": {
"policy": "auto_accept",
......@@ -8,7 +8,7 @@
}
},
{
"model": "im.memberrejectpolicy",
"model": "im.memberleavepolicy",
"pk": 2,
"fields": {
"policy": "owner_accepts",
......@@ -16,7 +16,7 @@
}
},
{
"model": "im.memberrejectpolicy",
"model": "im.memberleavepolicy",
"pk": 3,
"fields": {
"policy": "closed",
......
[
{
"model": "im.memberacceptpolicy",
"model": "im.memberjoinpolicy",
"pk": 1,
"fields": {
"policy": "auto_accept",
......@@ -8,7 +8,7 @@
}
},
{
"model": "im.memberacceptpolicy",
"model": "im.memberjoinpolicy",
"pk": 2,
"fields": {
"policy": "owner_accepts",
......@@ -16,7 +16,7 @@
}
},
{
"model": "im.memberacceptpolicy",
"model": "im.memberjoinpolicy",
"pk": 3,
"fields": {
"policy": "closed",
......
......@@ -922,8 +922,15 @@ class ProjectApplicationForm(forms.ModelForm):
class Meta:
model = ProjectDefinition
exclude = ('resource_grants', 'serial')
exclude = ('resource_grants', 'id')
def __init__(self, *args, **kwargs):
super(ProjectApplicationForm, self).__init__(*args, **kwargs)
instance = kwargs.get('instance')
if instance:
self.initial['comments'] = instance.projectapplication.comments
def clean(self):
userid = self.data.get('user', None)[0]
self.user = None
......@@ -960,8 +967,7 @@ class ProjectApplicationForm(forms.ModelForm):
return policies
def save(self, commit=True):
definition = super(ProjectApplicationForm, self).save(commit=commit)
definition.resource_policies=self.resource_policies
definition = super(ProjectApplicationForm, self).save(commit=False)
applicant = self.user
comments = self.cleaned_data.pop('comments', None)
try:
......@@ -970,6 +976,7 @@ class ProjectApplicationForm(forms.ModelForm):
precursor_application = None
return ProjectApplication.submit(
definition,
self.resource_policies,
applicant,
comments,
precursor_application,
......@@ -984,8 +991,32 @@ class ProjectSortForm(forms.Form):
('definition__start_date', 'Sort by Start Date'),
('definition__end_date', 'Sort by End Date'),
# ('approved_members_num', 'Sort by Participants'),
('definition__member_accept_policy', 'Sort by Member Accept Policy'),
('definition__member_reject_policy', 'Sort by Member Reject Policy')
('definition__member_join_policy__description', 'Sort by Member Join Policy'),
('definition__member_leave_policy__description', 'Sort by Member Leave Policy')
),
required=True
)
\ No newline at end of file
)
class AddProjectMembersForm(forms.Form):
q = forms.CharField(
max_length=800, widget=forms.Textarea, label=_('Add members'),
help_text=_(astakos_messages.ADD_PROJECT_MEMBERS_Q_HELP),
required=True)
def clean(self):
q = self.cleaned_data.get('q') or ''
users = q.split(',')
users = list(u.strip() for u in users if u)
db_entries = AstakosUser.objects.filter(email__in=users)
unknown = list(set(users) - set(u.email for u in db_entries))
if unknown:
raise forms.ValidationError(_(astakos_messages.UNKNOWN_USERS) % ','.join(unknown))
self.valid_users = db_entries
return self.cleaned_data
def get_valid_users(self):
"""Should be called after form cleaning"""
try:
return self.valid_users
except:
return ()
\ No newline at end of file
......@@ -347,7 +347,7 @@ class SendFeedbackError(SendMailError):
class ChangeEmailError(SendMailError):
def __init__(self):
self.message = self.message = _(astakos_messages.CHANGE_EMAIL_SEND_ERR)
self.message = _(astakos_messages.CHANGE_EMAIL_SEND_ERR)
super(ChangeEmailError, self).__init__()
......
......@@ -33,26 +33,44 @@
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from astakos.im.models import approve_application, ProjectApplication
class Command(BaseCommand):
args = "<project application serial>"
help = "Update project state"
def handle(self, *args, **options):
if len(args) < 1:
raise CommandError("Please provide a group identifier")
serial = args[0]
try:
approve_application(serial)
except ProjectApplication.DoesNotExist, e:
raise CommandError("Invalid serial")
except Exception, e:
import traceback
traceback.print_exc()
raise CommandError("Project application approval failed with: %s" % e)
else:
self.stdout.write("Project application has been successfully approved")
\ No newline at end of file
from django.core.management.base import NoArgsCommand
from astakos.im.models import ProjectApplication
class Command(NoArgsCommand):
help = "List resources"
option_list = NoArgsCommand.option_list + (
make_option('-c',
action='store_true',
dest='csv',
default=False,
help="Use pipes to separate values"),
)
def handle_noargs(self, **options):
apps = ProjectApplication.objects.select_related().all()
labels = ('id', 'name', 'status')
columns = (3, 40, 10)
if not options['csv']:
line = ' '.join(l.rjust(w) for l, w in zip(labels, columns))
self.stdout.write(line + '\n')
sep = '-' * len(line)
self.stdout.write(sep + '\n')
for app in apps:
fields = (
str(app.id),
app.definition.name,
app.status
)
if options['csv']:
line = '|'.join(fields)
else:
line = ' '.join(f.rjust(w) for f, w in zip(fields, columns))
self.stdout.write(line.encode('utf8') + '\n')
......@@ -34,74 +34,67 @@
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
from astakos.im.models import approve_application,
from astakos.im.models import _lookup_object, ProjectApplication, Project
@transaction.commit_on_success
class Command(BaseCommand):
args = "<project application serial>"
args = "<project application id>"
help = "Update project state"
option_list = BaseCommand.option_list + (
make_option('--approve',
action='store_true',
dest='approve',
default=False,
help="Approve group"),
make_option('--terminate',
action='store_true',
dest='terminate',
default=False,
help="Enable group"),
help="Terminate group"),
make_option('--suspend',
action='store_true',
dest='suspend',
default=False,
help="Disable group"),
make_option('--activate',
action='store_true',
dest='activate',
default=False,
help="Disable group"),
help="Suspend group")
)
def handle(self, *args, **options):
if len(args) < 1:
raise CommandError("Please provide a group identifier")
group = None
try:
if args[0].isdigit():
group = AstakosGroup.objects.get(id=args[0])
else:
group = AstakosGroup.objects.get(name=args[0])
except AstakosGroup.DoesNotExist, e:
raise CommandError("Invalid group")
app = None
p = None
try:
pname = options.get('add-permission')
if pname:
r, created = add_group_permission(group, pname)
if created:
self.stdout.write(
'Permission: %s created successfully\n' % pname)
if r == 0:
self.stdout.write(
'Group has already permission: %s\n' % pname)
else:
self.stdout.write(
'Permission: %s added successfully\n' % pname)
pname = options.get('delete-permission')
if pname:
r = remove_group_permission(group, pname)
if r < 0:
self.stdout.write(
'Invalid permission codename: %s\n' % pname)
elif r == 0:
self.stdout.write('Group has not permission: %s\n' % pname)
elif r > 0:
self.stdout.write(
'Permission: %s removed successfully\n' % pname)
id = int(args[0])
except ValueError:
raise CommandError('Invalid id')
else:
try:
# Is it a project application id?
app = _lookup_object(ProjectApplication, id=id)
except ProjectApplication.DoesNotExist:
try:
# Is it a project id?
p = _lookup_object(Project, id=id)
except Project.DoesNotExist:
raise CommandError('Invalid id')
try:
if options['approve']:
if not app:
raise CommandError('Project application id is required.')
app.approve()
if options.get('enable'):
group.enable()
elif options.get('disable'):
group.disable()
if app and app.status != 'Pending':
p = app.project
except Exception, e:
raise CommandError(e)
if options['terminate']:
p.terminate()
if options['suspend']:
p.suspend()
except BaseException, e:
import traceback
traceback.print_exc()
raise CommandError(e)
......@@ -129,9 +129,12 @@ INVALID_KEY_PARAMETER = 'Invalid key.'
DOMAIN_VALUE_ERR = 'Enter a valid domain.'
QH_SYNC_ERROR = 'Failed to get synchronized with quotaholder.'
UNIQUE_PROJECT_NAME_CONSTRAIN_ERR = 'The project name (as specified in its application\'s definition) must be unique among all active projects.'
INVALID_PROJECT = 'Project %(serial)s is invalid.'
NOT_ALIVE_PROJECT = 'Project %(serial)s is not alive.'
INVALID_PROJECT = 'Project %(id)s is invalid.'
NOT_ALIVE_PROJECT = 'Project %(id)s is not alive.'
NOT_ALLOWED = 'You do not have the permissions to perform this action.'
MEMBER_NUMBER_LIMIT_REACHED = 'Maximum participant number has been reached.'
MEMBER_ACCEPT_POLICY_CLOSED = 'The project member accept policy is cloesd.'
NO_APPLICANT = 'Project application requires an applicant. None found.'
\ No newline at end of file
MEMBER_JOIN_POLICY_CLOSED = 'The project member join policy is cloesd.'
MEMBER_LEAVE_POLICY_CLOSED = 'The project member leave policy is cloesd.'
NOT_MEMBERSHIP_REQUEST = 'There is no such a membership request.'
NO_APPLICANT = 'Project application requires an applicant. None found.'
ADD_PROJECT_MEMBERS_Q_HELP = 'Add comma separated user emails, eg. user1@user.com, user2@user.com'
\ No newline at end of file
......@@ -8,12 +8,20 @@ class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'MemberJoinPolicy'
db.create_table('im_memberjoinpolicy', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('policy', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
('description', self.gf('django.db.models.fields.CharField')(max_length=80)),
))
db.send_create_signal('im', ['MemberJoinPolicy'])
# Adding model 'ProjectMembershipHistory'
db.create_table('im_projectmembershiphistory', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.AstakosUser'])),
('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.Project'])),
('request_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 12, 8, 1, 2, 7, 352304))),
('request_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 12, 9, 11, 4, 41, 210148))),
('removal_date', self.gf('django.db.models.fields.DateField')(null=True)),
('rejection_date', self.gf('django.db.models.fields.DateField')(null=True)),
))
......@@ -24,7 +32,7 @@ class Migration(SchemaMigration):
# Adding model 'ProjectApplication'
db.create_table('im_projectapplication', (
('serial', self.gf('django.db.models.fields.CharField')(unique=True, max_length=30, primary_key=True)),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('applicant', self.gf('django.db.models.fields.related.ForeignKey')(related_name='my_project_applications', to=orm['im.AstakosUser'])),
('owner', self.gf('django.db.models.fields.related.ForeignKey')(related_name='own_project_applications', to=orm['im.AstakosUser'])),
('comments', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
......@@ -36,7 +44,7 @@ class Migration(SchemaMigration):
# Adding model 'Project'
db.create_table('im_project', (
('serial', self.gf('django.db.models.fields.CharField')(unique=True, max_length=30, primary_key=True)),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('application', self.gf('django.db.models.fields.related.OneToOneField')(related_name='project', unique=True, to=orm['im.ProjectApplication'])),
('creation_date', self.gf('django.db.models.fields.DateTimeField')()),
('last_approval_date', self.gf('django.db.models.fields.DateTimeField')(null=True)),
......@@ -52,7 +60,7 @@ class Migration(SchemaMigration):
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('person', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.AstakosUser'])),
('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.Project'])),
('request_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 12, 8, 1, 2, 7, 351571))),
('request_date', self.gf('django.db.models.fields.DateField')(default=datetime.datetime(2012, 12, 9, 11, 4, 41, 209391))),
('acceptance_date', self.gf('django.db.models.fields.DateField')(null=True, db_index=True)),
))
db.send_create_signal('im', ['ProjectMembership'])
......@@ -60,28 +68,28 @@ class Migration(SchemaMigration):
# Adding unique constraint on 'ProjectMembership', fields ['person', 'project']
db.create_unique('im_projectmembership', ['person_id', 'project_id'])
# Adding model 'MemberAcceptPolicy'
db.create_table('im_memberacceptpolicy', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('policy', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
('description', self.gf('django.db.models.fields.CharField')(max_length=80)),
))
db.send_create_signal('im', ['MemberAcceptPolicy'])
# Adding model 'ProjectDefinition'
db.create_table('im_projectdefinition', (
('serial', self.gf('django.db.models.fields.CharField')(unique=True, max_length=30, primary_key=True)),
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=80)),
('homepage', self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True)),
('description', self.gf('django.db.models.fields.TextField')(null=True)),
('start_date', self.gf('django.db.models.fields.DateTimeField')()),
('end_date', self.gf('django.db.models.fields.DateTimeField')()),
('member_accept_policy', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.MemberAcceptPolicy'])),
('member_reject_policy', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.MemberRejectPolicy'])),
('member_join_policy', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.MemberJoinPolicy'])),
('member_leave_policy', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['im.MemberLeavePolicy'])),
('limit_on_members_number', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)),
))
db.send_create_signal('im', ['ProjectDefinition'])
# Adding model 'MemberLeavePolicy'
db.create_table('im_memberleavepolicy', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('policy', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
('description', self.gf('django.db.models.fields.CharField')(max_length=80)),
))
db.send_create_signal('im', ['MemberLeavePolicy'])
# Adding model 'ProjectResourceGrant'
db.create_table('im_projectresourcegrant', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
......@@ -95,14 +103,6 @@ class Migration(SchemaMigration):
# Adding unique constraint on 'ProjectResourceGrant', fields ['resource', 'project_definition']
db.create_unique('im_projectresourcegrant', ['resource_id', 'project_definition_id'])
# Adding model 'MemberRejectPolicy'
db.create_table('im_memberrejectpolicy', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('policy', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
('description', self.gf('django.db.models.fields.CharField')(max_length=80)),
))
db.send_create_signal('im', ['MemberRejectPolicy'])
def backwards(self, orm):
......@@ -115,6 +115,9 @@ class Migration(SchemaMigration):
# Removing unique constraint on 'ProjectMembershipHistory', fields ['person', 'project']
db.delete_unique('im_projectmembershiphistory', ['person_id', 'project_id'])
# Deleting model 'MemberJoinPolicy'
db.delete_table('im_memberjoinpolicy')
# Deleting model 'ProjectMembershipHistory'
db.delete_table('im_projectmembershiphistory')
......@@ -127,18 +130,15 @@ class Migration(SchemaMigration):
# Deleting model 'ProjectMembership'
db.delete_table('im_projectmembership')
# Deleting model 'MemberAcceptPolicy'
db.delete_table('im_memberacceptpolicy')
# Deleting model 'ProjectDefinition'
db.delete_table('im_projectdefinition')
# Deleting model 'MemberLeavePolicy'
db.delete_table('im_memberleavepolicy')
# Deleting model 'ProjectResourceGrant'
db.delete_table('im_projectresourcegrant')
# Deleting model 'MemberRejectPolicy'
db.delete_table('im_memberrejectpolicy')
models = {
'auth.group': {
......@@ -185,14 +185,14 @@ class Migration(SchemaMigration):
},
'im.approvalterms': {
'Meta': {'object_name': 'ApprovalTerms'},
'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 8, 1, 2, 7, 341713)', 'db_index': 'True'}),
'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 198398)', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'location': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
'im.astakosgroup': {
'Meta': {'object_name': 'AstakosGroup', '_ormbases': ['auth.Group']},
'approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 8, 1, 2, 7, 333863)'}),
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 189261)'}),
'desc': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'estimated_participants': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'expiration_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
......@@ -258,7 +258,7 @@ class Migration(SchemaMigration):
'activation_key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'new_email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'requested_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 8, 1, 2, 7, 343372)'}),
'requested_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 200303)'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'emailchange_user'", 'unique': 'True', 'to': "orm['im.AstakosUser']"})
},
'im.groupkind': {
......@@ -277,14 +277,14 @@ class Migration(SchemaMigration):
'realname': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'im.memberacceptpolicy': {
'Meta': {'object_name': 'MemberAcceptPolicy'},
'im.memberjoinpolicy': {
'Meta': {'object_name': 'MemberJoinPolicy'},
'description': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'policy': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
},
'im.memberrejectpolicy': {
'Meta': {'object_name': 'MemberRejectPolicy'},
'im.memberleavepolicy': {
'Meta': {'object_name': 'MemberLeavePolicy'},
'description': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'policy': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'})
......@@ -292,7 +292,7 @@ class Migration(SchemaMigration):
'im.membership': {
'Meta': {'unique_together': "(('person', 'group'),)", 'object_name': 'Membership'},
'date_joined': ('django.db.models.fields.DateField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'date_requested': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 8, 1, 2, 7, 339429)', 'blank': 'True'}),
'date_requested': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime(2012, 12, 9, 11, 4, 41, 196071)', 'blank': 'True'}),
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosGroup']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.AstakosUser']"})
......@@ -314,11 +314,11 @@ class Migration(SchemaMigration):
'Meta': {'object_name': 'Project'},
'application': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'project'", 'unique': 'True', 'to': "orm['im.ProjectApplication']"}),
'creation_date': ('django.db.models.fields.DateTimeField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_application_synced': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'last_project'", 'unique': 'True', 'null': 'True', 'to': "orm['im.ProjectApplication']"}),
'last_approval_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['im.AstakosUser']", 'through': "orm['im.ProjectMembership']", 'symmetrical': 'False'}),
'membership_dirty': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'serial': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30', 'primary_key': 'True'}),
'termination_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'termination_start_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'})
},
......@@ -327,22 +327,22 @@ class Migration(SchemaMigration):
'applicant': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'my_project_applications'", 'to': "orm['im.AstakosUser']"}),
'comments': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'definition': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectDefinition']", 'unique': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'issue_date': ('django.db.models.fields.DateTimeField', [], {}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'own_project_applications'", 'to': "orm['im.AstakosUser']"}),
'precursor_application': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectApplication']", 'unique': 'True', 'null': 'True', 'blank': 'True'}),
'serial': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30', 'primary_key': 'True'})
'precursor_application': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['im.ProjectApplication']", 'unique': 'True', 'null': 'True', 'blank': 'True'})
},
'im.projectdefinition': {
'Meta': {'object_name': 'ProjectDefinition'},
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'end_date': ('django.db.models.fields.DateTimeField', [], {}),
'homepage': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'limit_on_members_number': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
'member_accept_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberAcceptPolicy']"}),
'member_reject_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberRejectPolicy']"}),
'member_join_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberJoinPolicy']"}),
'member_leave_policy': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['im.MemberLeavePolicy']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),