add project permissions managment page
This commit is contained in:
parent
b5c525a299
commit
4d7ab944c2
12 changed files with 256 additions and 17 deletions
|
@ -26,15 +26,21 @@ class IssueForm(forms.Form):
|
||||||
class CommentForm(forms.Form):
|
class CommentForm(forms.Form):
|
||||||
comment = forms.CharField(widget=MarkdownWidget)
|
comment = forms.CharField(widget=MarkdownWidget)
|
||||||
|
|
||||||
class GlobalPermissionForm(forms.ModelForm):
|
class PermissionForm(forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = GlobalPermission
|
model = PermissionModel
|
||||||
exclude = ['content_type']
|
exclude = []
|
||||||
|
abstract = True
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
||||||
data = super(GlobalPermissionForm, self).clean()
|
data = super(PermissionForm, self).clean()
|
||||||
|
|
||||||
|
if not 'grantee_name' in data or not 'grantee_type' in data:
|
||||||
|
# a field required error will be printed so we dont care
|
||||||
|
return data
|
||||||
|
|
||||||
name = data['grantee_name']
|
name = data['grantee_name']
|
||||||
|
|
||||||
if int(data['grantee_type']) == PermissionModel.GRANTEE_USER:
|
if int(data['grantee_type']) == PermissionModel.GRANTEE_USER:
|
||||||
|
@ -48,3 +54,15 @@ class GlobalPermissionForm(forms.ModelForm):
|
||||||
raise ValidationError("Team '%s' does not exists." %name)
|
raise ValidationError("Team '%s' does not exists." %name)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
class GlobalPermissionForm(PermissionForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = GlobalPermission
|
||||||
|
exclude = []
|
||||||
|
|
||||||
|
class ProjectPermissionForm(PermissionForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = ProjectPermission
|
||||||
|
exclude = []
|
||||||
|
|
19
issue/migrations/0009_auto_20140808_1635.py
Normal file
19
issue/migrations/0009_auto_20140808_1635.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('issue', '0008_auto_20140808_0222'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='projectpermission',
|
||||||
|
name='project',
|
||||||
|
field=models.ForeignKey(editable=False, to='issue.Project'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -388,7 +388,7 @@ class GlobalPermission(PermissionModel):
|
||||||
|
|
||||||
class ProjectPermission(PermissionModel):
|
class ProjectPermission(PermissionModel):
|
||||||
|
|
||||||
project = models.ForeignKey(Project, related_name='permissions')
|
project = models.ForeignKey(Project, related_name='permissions', editable=False)
|
||||||
|
|
||||||
create_issue = models.BooleanField(default=True)
|
create_issue = models.BooleanField(default=True)
|
||||||
modify_issue = models.BooleanField(default=False)
|
modify_issue = models.BooleanField(default=False)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h1>
|
<h1>
|
||||||
Permissions
|
Global permissions
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<a href="{% url 'add-global-permission' %}"><button class="btn btn-success">Add new permission</button></a>
|
<a href="{% url 'add-global-permission' %}"><button class="btn btn-success">Add new permission</button></a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,23 +18,23 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if permissions.count %}
|
{% if permissions.count %}
|
||||||
<table class="table">
|
<table class="table table-bordered">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Create project?</th>
|
<th class="text-center">Create project?</th>
|
||||||
<th>Modify project?</th>
|
<th class="text-center">Modify project?</th>
|
||||||
<th>Delete project?</th>
|
<th class="text-center">Delete project?</th>
|
||||||
<th class="col-md-2"></th>
|
<th class="col-md-2"></th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for perm in permissions %}
|
{% for perm in permissions %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ perm.type }}</td>
|
<td>{{ perm.type }}</td>
|
||||||
<td>{{ perm.name }}</td>
|
<td>{{ perm.name }}</td>
|
||||||
<td><a href="{% url 'toggle-global-permission' perm.id 'create-project' %}">{{ perm.create_project|boolean }}</a></td>
|
<td class="text-center"><a href="{% url 'toggle-global-permission' perm.id 'create-project' %}">{{ perm.create_project|boolean }}</a></td>
|
||||||
<td><a href="{% url 'toggle-global-permission' perm.id 'modify-project' %}">{{ perm.modify_project|boolean }}</a></td>
|
<td class="text-center"><a href="{% url 'toggle-global-permission' perm.id 'modify-project' %}">{{ perm.modify_project|boolean }}</a></td>
|
||||||
<td><a href="{% url 'toggle-global-permission' perm.id 'delete-project' %}">{{ perm.delete_project|boolean }}</a></td>
|
<td class="text-center"><a href="{% url 'toggle-global-permission' perm.id 'delete-project' %}">{{ perm.delete_project|boolean }}</a></td>
|
||||||
<td class="text-right">
|
<td class="text-center">
|
||||||
<a href="{% url 'edit-global-permission' perm.id %}"><button class="btn btn-primary btn-xs"><span class="glyphicon glyphicon-edit"></span> Edit</button></a>
|
<a href="{% url 'edit-global-permission' perm.id %}"><button class="btn btn-primary btn-xs"><span class="glyphicon glyphicon-edit"></span> Edit</button></a>
|
||||||
<a href="{% url 'delete-global-permission' perm.id %}"><button class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-remove"></span> Delete</button></a>
|
<a href="{% url 'delete-global-permission' perm.id %}"><button class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-remove"></span> Delete</button></a>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
{% block page_title %}{{ project }}{% endblock %}
|
{% block page_title %}{{ project }}{% endblock %}
|
||||||
|
|
||||||
{% block projectmenu %}
|
{% block projectmenu %}
|
||||||
|
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'list-project-permission' project.name %}">Manage permissions</a></li>
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'edit-project' project.name %}">Modify this project</a></li>
|
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'edit-project' project.name %}">Modify this project</a></li>
|
||||||
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'delete-project' project.name %}">Delete this project</a></li>
|
<li role="presentation"><a role="menuitem" tabindex="-1" href="{% url 'delete-project' project.name %}">Delete this project</a></li>
|
||||||
|
<li role="presentation" class="divider"></li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block navbar %}
|
{% block navbar %}
|
||||||
|
|
13
issue/templates/issue/project_add.html
Normal file
13
issue/templates/issue/project_add.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<form action="" method="post" role="form">
|
||||||
|
{{ form|crispy }}
|
||||||
|
{% csrf_token %}
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'issue/project.html' %}
|
||||||
|
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
|
27
issue/templates/issue/project_permission_edit.html
Normal file
27
issue/templates/issue/project_permission_edit.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{% extends 'issue/project.html' %}
|
||||||
|
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
|
||||||
|
<div class="panel-heading clearfix">
|
||||||
|
<h1>
|
||||||
|
Permissions of {{ project }} project
|
||||||
|
<div class="pull-right">
|
||||||
|
<a href="{% url 'list-project-permission' project.name %}"><button class="btn btn-warning">Go back to list</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<form action="" method="post" role="form">
|
||||||
|
{{ form|crispy }}
|
||||||
|
{% csrf_token %}
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
76
issue/templates/issue/project_permission_list.html
Normal file
76
issue/templates/issue/project_permission_list.html
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{% extends 'issue/project.html' %}
|
||||||
|
|
||||||
|
{% load django_markdown %}
|
||||||
|
{% load issue_filters %}
|
||||||
|
{% load issue_tags %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h1>
|
||||||
|
Permissions of {{ project }} project
|
||||||
|
<div class="pull-right">
|
||||||
|
<a href="{% url 'add-project-permission' project.name %}"><button class="btn btn-success">Add new permission</button></a>
|
||||||
|
</div>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if permissions.count %}
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th rowspan="2">Type</th>
|
||||||
|
<th rowspan="2">Name</th>
|
||||||
|
<th colspan="3" class="text-center">Issue</th>
|
||||||
|
<th colspan="3" class="text-center">Comment</th>
|
||||||
|
<th colspan="3" class="text-center">Label</th>
|
||||||
|
<th colspan="3" class="text-center">Milestone</th>
|
||||||
|
<th class="col-md-2"></th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">{% vertical 'Create?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Modify?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Delete?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Create?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Modify?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Delete?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Create?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Modify?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Delete?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Create?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Modify?' %}</th>
|
||||||
|
<th class="text-center">{% vertical 'Delete?' %}</th>
|
||||||
|
<th class="col-md-2"></th>
|
||||||
|
</tr>
|
||||||
|
{% for perm in permissions %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ perm.type }}</td>
|
||||||
|
<td>{{ perm.name }}</td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'create-issue' %}">{{ perm.create_issue|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'modify-issue' %}">{{ perm.modify_issue|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'delete-issue' %}">{{ perm.delete_issue|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'create-comment' %}">{{ perm.create_comment|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'modify-comment' %}">{{ perm.modify_comment|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'delete-comment' %}">{{ perm.delete_comment|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'create-label' %}">{{ perm.create_label|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'modify-label' %}">{{ perm.modify_label|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'delete-label' %}">{{ perm.delete_label|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'create-milestone' %}">{{ perm.create_milestone|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'modify-milestone' %}">{{ perm.modify_milestone|boolean }}</a></td>
|
||||||
|
<td class="text-center"><a href="{% url 'toggle-project-permission' project.name perm.id 'delete-milestone' %}">{{ perm.delete_milestone|boolean }}</a></td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a href="{% url 'edit-project-permission' project.name perm.id %}"><button class="btn btn-primary btn-xs"><span class="glyphicon glyphicon-edit"></span> Edit</button></a>
|
||||||
|
<a href="{% url 'delete-project-permission' project.name perm.id %}"><button class="btn btn-danger btn-xs"><span class="glyphicon glyphicon-remove"></span> Delete</button></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<div class="panel-body">
|
||||||
|
There aren't any permissions defined yet.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -48,3 +48,7 @@ def same_author(context, author):
|
||||||
url += '?q=is:open%20author:' + author.username
|
url += '?q=is:open%20author:' + author.username
|
||||||
|
|
||||||
return mark_safe(url)
|
return mark_safe(url)
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def vertical(string):
|
||||||
|
return string.replace("", "\0").strip("\0").replace("\0", "<br />")
|
||||||
|
|
|
@ -28,6 +28,11 @@ urlpatterns = [
|
||||||
url(r'^(?P<project>[a-z0-9_-]+)/milestones/(?P<name>[a-z0-9_.-]+)/close$', 'issue.views.milestone_close', name='close-milestone'),
|
url(r'^(?P<project>[a-z0-9_-]+)/milestones/(?P<name>[a-z0-9_.-]+)/close$', 'issue.views.milestone_close', name='close-milestone'),
|
||||||
url(r'^(?P<project>[a-z0-9_-]+)/milestones/(?P<name>[a-z0-9_.-]+)/reopen$', 'issue.views.milestone_reopen', name='reopen-milestone'),
|
url(r'^(?P<project>[a-z0-9_-]+)/milestones/(?P<name>[a-z0-9_.-]+)/reopen$', 'issue.views.milestone_reopen', name='reopen-milestone'),
|
||||||
url(r'^(?P<project>[a-z0-9_-]+)/milestones/(?P<name>[a-z0-9_.-]+)/delete$', 'issue.views.milestone_delete', name='delete-milestone'),
|
url(r'^(?P<project>[a-z0-9_-]+)/milestones/(?P<name>[a-z0-9_.-]+)/delete$', 'issue.views.milestone_delete', name='delete-milestone'),
|
||||||
|
url(r'^(?P<project>[a-z0-9_-]+)/permissions$', 'issue.views.project_permission_list', name='list-project-permission'),
|
||||||
|
url(r'^(?P<project>[a-z0-9_-]+)/permissions/add$', 'issue.views.project_permission_edit', name='add-project-permission'),
|
||||||
|
url(r'^(?P<project>[a-z0-9_-]+)/permissions/(?P<id>[0-9]+)/edit$', 'issue.views.project_permission_edit', name='edit-project-permission'),
|
||||||
|
url(r'^(?P<project>[a-z0-9_-]+)/permissions/(?P<id>[0-9]+)/toggle/(?P<perm>[a-z-]+)$', 'issue.views.project_permission_toggle', name='toggle-project-permission'),
|
||||||
|
url(r'^(?P<project>[a-z0-9_-]+)/permissions/(?P<id>[0-9]+)/delete$', 'issue.views.project_permission_delete', name='delete-project-permission'),
|
||||||
url(r'^permissions$', 'issue.views.global_permission_list', name='list-global-permission'),
|
url(r'^permissions$', 'issue.views.global_permission_list', name='list-global-permission'),
|
||||||
url(r'^permissions/add$', 'issue.views.global_permission_edit', name='add-global-permission'),
|
url(r'^permissions/add$', 'issue.views.global_permission_edit', name='add-global-permission'),
|
||||||
url(r'^permissions/(?P<id>[0-9]+)/edit$', 'issue.views.global_permission_edit', name='edit-global-permission'),
|
url(r'^permissions/(?P<id>[0-9]+)/edit$', 'issue.views.global_permission_edit', name='edit-global-permission'),
|
||||||
|
|
|
@ -34,8 +34,10 @@ def global_permission_edit(request, id=None):
|
||||||
|
|
||||||
if id:
|
if id:
|
||||||
permission = get_object_or_404(GlobalPermission, id=id)
|
permission = get_object_or_404(GlobalPermission, id=id)
|
||||||
|
new = False
|
||||||
else:
|
else:
|
||||||
permission = None
|
permission = None
|
||||||
|
new = True
|
||||||
|
|
||||||
form = GlobalPermissionForm(request.POST or None, instance=permission)
|
form = GlobalPermissionForm(request.POST or None, instance=permission)
|
||||||
|
|
||||||
|
@ -43,7 +45,10 @@ def global_permission_edit(request, id=None):
|
||||||
|
|
||||||
permission = form.save()
|
permission = form.save()
|
||||||
|
|
||||||
messages.success(request, 'Permission added successfully.')
|
if new:
|
||||||
|
messages.success(request, 'Permission added successfully.')
|
||||||
|
else:
|
||||||
|
messages.success(request, 'Permission updated successfully.')
|
||||||
|
|
||||||
return redirect('list-global-permission')
|
return redirect('list-global-permission')
|
||||||
|
|
||||||
|
@ -77,8 +82,77 @@ def global_permission_delete(request, id):
|
||||||
|
|
||||||
permission.delete()
|
permission.delete()
|
||||||
|
|
||||||
|
messages.success(request, 'Permission deleted successfully.')
|
||||||
|
|
||||||
return redirect('list-global-permission')
|
return redirect('list-global-permission')
|
||||||
|
|
||||||
|
def project_permission_list(request, project):
|
||||||
|
|
||||||
|
permissions = ProjectPermission.objects.filter(project=project)
|
||||||
|
|
||||||
|
c = {
|
||||||
|
'project': project,
|
||||||
|
'permissions': permissions,
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, 'issue/project_permission_list.html', c)
|
||||||
|
|
||||||
|
def project_permission_edit(request, project, id=None):
|
||||||
|
|
||||||
|
if id:
|
||||||
|
permission = get_object_or_404(ProjectPermission, project=project, id=id)
|
||||||
|
else:
|
||||||
|
permission = None
|
||||||
|
|
||||||
|
form = ProjectPermissionForm(request.POST or None, instance=permission)
|
||||||
|
|
||||||
|
if request.method == 'POST' and form.is_valid():
|
||||||
|
|
||||||
|
permission = form.save(commit=False)
|
||||||
|
if not hasattr(permission, 'project'):
|
||||||
|
permission.project = project
|
||||||
|
messages.success(request, 'Permission added successfully.')
|
||||||
|
else:
|
||||||
|
messages.success(request, 'Permission updated successfully.')
|
||||||
|
permission.save()
|
||||||
|
|
||||||
|
return redirect('list-project-permission', project.name)
|
||||||
|
|
||||||
|
c = {
|
||||||
|
'project': project,
|
||||||
|
'form': form,
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, 'issue/project_permission_edit.html', c)
|
||||||
|
|
||||||
|
def project_permission_toggle(request, project, id, perm):
|
||||||
|
|
||||||
|
permission = get_object_or_404(ProjectPermission, project=project, id=id)
|
||||||
|
|
||||||
|
# to be sure to dont modify other attribut with the following trick
|
||||||
|
if not '-' in perm:
|
||||||
|
raise Http404
|
||||||
|
perm = perm.replace('-', '_')
|
||||||
|
|
||||||
|
if hasattr(permission, perm):
|
||||||
|
print(type(getattr(permission, perm)))
|
||||||
|
setattr(permission, perm, not getattr(permission, perm))
|
||||||
|
permission.save()
|
||||||
|
else:
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
return redirect('list-project-permission', project.name)
|
||||||
|
|
||||||
|
def project_permission_delete(request, project, id):
|
||||||
|
|
||||||
|
permission = get_object_or_404(ProjectPermission, project=project, id=id)
|
||||||
|
|
||||||
|
permission.delete()
|
||||||
|
|
||||||
|
messages.success(request, 'Permission deleted successfully.')
|
||||||
|
|
||||||
|
return redirect('list-project-permission', project.name)
|
||||||
|
|
||||||
def project_list(request):
|
def project_list(request):
|
||||||
|
|
||||||
if not request.projects.exists():
|
if not request.projects.exists():
|
||||||
|
@ -113,7 +187,7 @@ def project_add(request):
|
||||||
'form': form,
|
'form': form,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'issue/project_edit.html', c)
|
return render(request, 'issue/project_add.html', c)
|
||||||
|
|
||||||
def project_edit(request, project):
|
def project_edit(request, project):
|
||||||
|
|
||||||
|
@ -136,6 +210,7 @@ def project_edit(request, project):
|
||||||
return redirect('list-issue', project.name)
|
return redirect('list-issue', project.name)
|
||||||
|
|
||||||
c = {
|
c = {
|
||||||
|
'project': project,
|
||||||
'form': form,
|
'form': form,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue