mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-17 13:32:15 +00:00
Event checklist crew works
Mostly - its not happy with timezones
This commit is contained in:
@@ -10,6 +10,7 @@ from django.contrib.auth.forms import AuthenticationForm
|
||||
from captcha.fields import ReCaptchaField
|
||||
from reversion import revisions as reversion
|
||||
import simplejson
|
||||
from datetime import datetime
|
||||
|
||||
from RIGS import models
|
||||
|
||||
@@ -172,17 +173,17 @@ class EventRiskAssessmentForm(forms.ModelForm):
|
||||
|
||||
|
||||
class EventChecklistForm(forms.ModelForm):
|
||||
# Parsed from incoming form data by clean, then saved into models when the form is saved
|
||||
items = {}
|
||||
|
||||
# There's probably a thousand better ways to do this, but this one is mine
|
||||
def clean(self):
|
||||
vehicles = {key: val for key, val in self.data.items()
|
||||
if key.startswith('vehicle')}
|
||||
drivers = {key: val for key, val in self.data.items()
|
||||
if key.startswith('driver')}
|
||||
for key in vehicles:
|
||||
pk = int(key.split('_')[1])
|
||||
driver_key = 'driver_' + str(pk)
|
||||
if(drivers[driver_key] == ''):
|
||||
if(self.data[driver_key] == ''):
|
||||
raise forms.ValidationError('Add a driver to vehicle ' + str(pk), code='vehicle_mismatch')
|
||||
else:
|
||||
try:
|
||||
@@ -191,10 +192,36 @@ class EventChecklistForm(forms.ModelForm):
|
||||
item = models.EventChecklistVehicle()
|
||||
|
||||
item.vehicle = vehicles['vehicle_' + str(pk)]
|
||||
item.driver = models.Profile.objects.get(pk=drivers['driver_' + str(pk)])
|
||||
item.driver = models.Profile.objects.get(pk=self.data[driver_key])
|
||||
item.full_clean('checklist')
|
||||
|
||||
# item does not have a database pk yet as it isn't saved
|
||||
self.items[pk] = item
|
||||
self.items['v' + str(pk)] = item
|
||||
|
||||
crewmembers = {key: val for key, val in self.data.items()
|
||||
if key.startswith('crewmember')}
|
||||
other_fields = ['start','role','end']
|
||||
for key in crewmembers:
|
||||
pk = int(key.split('_')[1])
|
||||
|
||||
for field in other_fields:
|
||||
value = self.data['{}_{}'.format(field,pk)]
|
||||
if value == '':
|
||||
raise forms.ValidationError('Add a {} to crewmember {}'.format(field, pk), code='{}_mismatch'.format(field))
|
||||
|
||||
try:
|
||||
item = models.EventChecklistCrew.objects.get(pk=pk)
|
||||
except models.EventChecklistCrew.DoesNotExist:
|
||||
item = models.EventChecklistCrew()
|
||||
|
||||
item.crewmember = models.Profile.objects.get(pk=self.data['crewmember_' + str(pk)])
|
||||
item.start = self.data['start_' + str(pk)]
|
||||
item.role = self.data['role_' + str(pk)]
|
||||
item.end = self.data['end_' + str(pk)]
|
||||
item.full_clean('checklist')
|
||||
|
||||
# item does not have a database pk yet as it isn't saved
|
||||
self.items['c' + str(pk)] = item
|
||||
|
||||
return super(EventChecklistForm, self).clean()
|
||||
|
||||
@@ -203,15 +230,18 @@ class EventChecklistForm(forms.ModelForm):
|
||||
if (commit):
|
||||
# Remove all existing, to be recreated from the form
|
||||
checklist.vehicles.all().delete()
|
||||
checklist.save()
|
||||
checklist.crew.all().delete()
|
||||
|
||||
for key in self.items:
|
||||
item = self.items[key]
|
||||
reversion.add_to_revision(item)
|
||||
# finish and save new database items
|
||||
item.checklist = checklist
|
||||
item.full_clean()
|
||||
item.save()
|
||||
|
||||
checklist.save()
|
||||
|
||||
self.items.clear()
|
||||
|
||||
return checklist
|
||||
|
||||
31
RIGS/migrations/0047_auto_20200829_2105.py
Normal file
31
RIGS/migrations/0047_auto_20200829_2105.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 3.1 on 2020-08-29 20:05
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('RIGS', '0046_auto_20200828_1246'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='eventchecklistvehicle',
|
||||
name='driver',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='vehicles', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='EventChecklistCrew',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('role', models.CharField(max_length=255, null=True)),
|
||||
('start', models.DateTimeField(blank=True, null=True)),
|
||||
('end', models.DateTimeField(blank=True, null=True)),
|
||||
('checklist', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='crew', to='RIGS.eventchecklist')),
|
||||
('crewmember', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='crewed', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -635,7 +635,7 @@ class RiskAssessment(models.Model, RevisionMixin):
|
||||
return "%i - %s" % (self.pk, self.event)
|
||||
|
||||
|
||||
@reversion.register(follow=['vehicles', ])
|
||||
@reversion.register(follow=['vehicles', 'crew'])
|
||||
class EventChecklist(models.Model, RevisionMixin):
|
||||
event = models.OneToOneField('Event', on_delete=models.CASCADE)
|
||||
|
||||
@@ -680,9 +680,23 @@ class EventChecklist(models.Model, RevisionMixin):
|
||||
class EventChecklistVehicle(models.Model):
|
||||
checklist = models.ForeignKey('EventChecklist', related_name='vehicles', blank=True, on_delete=models.CASCADE)
|
||||
vehicle = models.CharField(max_length=255)
|
||||
driver = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='drivers', on_delete=models.CASCADE)
|
||||
driver = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='vehicles', on_delete=models.CASCADE)
|
||||
|
||||
reversion_hide = True
|
||||
|
||||
def __str__(self):
|
||||
return "{} driven by {}".format(self.vehicle, str(self.driver))
|
||||
|
||||
|
||||
@reversion.register
|
||||
class EventChecklistCrew(models.Model):
|
||||
checklist = models.ForeignKey('EventChecklist', related_name='crew', blank=True, on_delete=models.CASCADE)
|
||||
crewmember = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='crewed', on_delete=models.CASCADE)
|
||||
role = models.CharField(max_length=255)
|
||||
start = models.DateTimeField()
|
||||
end = models.DateTimeField()
|
||||
|
||||
reversion_hide = True
|
||||
|
||||
def __str__(self):
|
||||
return "{} ({})".format(str(self.crewmember), self.role)
|
||||
|
||||
@@ -61,6 +61,16 @@
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card card-default mb-3">
|
||||
<div class="card-header">Crew Record</div>
|
||||
<div class="card-body">
|
||||
<ul>
|
||||
{% for i in object.crew.all %}
|
||||
<li>{{i}}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card card-default mb-3">
|
||||
<div class="card-header">Power</div>
|
||||
<div class="card-body">
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
{% if object.medium_event %}
|
||||
$('#small-event').slideUp();
|
||||
$('#medium-event').slideDown();
|
||||
$('#size-selector button[data-event-size=1]').addClass('active');
|
||||
{% else %}
|
||||
$('#small-event').slideDown();
|
||||
$('#medium-event').slideUp();
|
||||
$('#size-selector button[data-event-size=0]').addClass('active');
|
||||
{% endif%}
|
||||
{% endif %}
|
||||
$('#size-selector button').on('click', function () {
|
||||
@@ -53,24 +55,29 @@
|
||||
$('#medium-event').slideUp();
|
||||
}
|
||||
});
|
||||
$('#vehicle-add').on('click', function (event) {
|
||||
$('button[data-action=add]').on('click', function (event) {
|
||||
event.preventDefault();
|
||||
var newID = Number($('#vehiclest').attr('data-pk'));
|
||||
$('#vehicles_new').clone().attr('style', "").attr('id', 'vehicles_' + newID).appendTo('#vehiclest');
|
||||
$('#vehicles_' + newID).find('select,input').attr('name', function(){
|
||||
return this.name.split('_')[0] + '_' + newID;
|
||||
//Disabled prevents the hidden row being sent to the form
|
||||
}).removeAttr('disabled');
|
||||
$('#vehicles_' + newID).find('button[data-action=delete]').attr('data-id', newID);
|
||||
$('#vehicles_' + newID).find('select').addClass('selectpicker');
|
||||
$('#vehicles_' + newID).find('.selectpicker').selectpicker('refresh');
|
||||
var target = $($(this).attr('data-target'));
|
||||
var newID = Number(target.attr('data-pk'));
|
||||
var newRow = $($(this).attr('data-clone'))
|
||||
.clone().attr('style', "")
|
||||
.attr('id', function(i, val){
|
||||
return val.split("_")[0] + '_' + newID;
|
||||
})
|
||||
.appendTo(target);
|
||||
newRow.find('select,input').attr('name', function(i, val){
|
||||
return val.split("_")[0] + '_' + newID;
|
||||
})//Disabled is to prevent the hidden row being sent to the form
|
||||
.removeAttr('disabled');
|
||||
newRow.find('button[data-action=delete]').attr('data-id', newID);
|
||||
newRow.find('select').addClass('selectpicker');
|
||||
newRow.find('.selectpicker').selectpicker('refresh');
|
||||
$(".selectpicker").each(function(){initPicker($(this))});
|
||||
$('#vehiclest').attr('data-pk', newID - 1);
|
||||
$(target).attr('data-pk', newID - 1);
|
||||
});
|
||||
$('button[data-action=delete]').on('click', function(event) {
|
||||
event.preventDefault();
|
||||
console.log($(this).attr('data-id'));
|
||||
$('#vehicles_' + $(this).attr('data-id')).remove();
|
||||
$($(this).attr('data-target') + '_' + $(this).attr('data-id')).remove();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -124,11 +131,8 @@
|
||||
<tbody id="vehiclest" data-pk="-1">
|
||||
<tr id="vehicles_new" style="display: none;">
|
||||
<td><input type="text" class="form-control" name="vehicle_new" disabled="true"/></td>
|
||||
<td>
|
||||
<select class="form-control" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" name="driver_new" disabled="true">
|
||||
</select>
|
||||
</td>
|
||||
<td><button class="btn btn-danger" data-action='delete'><span class="fas fa-times"></span></button</td>
|
||||
<td><select class="form-control" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" name="driver_new" disabled="true"></select></td>
|
||||
<td><button class="btn btn-danger" data-action='delete' data-target='#vehicle'><span class="fas fa-times"></span></button</td>
|
||||
</tr>
|
||||
{# TODO Add required to all fields on row when one is edited #}
|
||||
{% for i in object.vehicles.all %}
|
||||
@@ -141,13 +145,13 @@
|
||||
{% endif %}
|
||||
</select>
|
||||
</td>
|
||||
<td><button class="btn btn-danger" data-id='{{i.pk}}' data-action='delete'><span class="fas fa-times"></span></button</td>
|
||||
<td><button class="btn btn-danger" data-id='{{i.pk}}' data-action='delete' data-target='#vehicle'><span class="fas fa-times"></span></button</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="text-right">
|
||||
<button class="btn btn-secondary" id="vehicle-add"><span class="fas fa-plus"></span> Add Vehicle</button>
|
||||
<button class="btn btn-secondary" id="vehicle-add" data-action='add' data-target='#vehiclest' data-clone='#vehicles_new'><span class="fas fa-plus"></span> Add Vehicle</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -184,23 +188,38 @@
|
||||
<th scope="col">Start Time</th>
|
||||
<th scope="col">Role</th>
|
||||
<th scope="col">End Time</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for i in '012'|make_list %}
|
||||
<tr>
|
||||
|
||||
<th scope="row">
|
||||
</th>
|
||||
<td><input type="time" class="form-control"/></td>
|
||||
<td><input type="text" class="form-control"/></td>
|
||||
<td><input type="time" class="form-control"/></td>
|
||||
<tbody id="crewmemberst" data-pk="-1">
|
||||
<tr id="crew_new" style="display: none;">
|
||||
<td>
|
||||
<select name="crewmember_new" class="form-control" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" disabled="true"></select>
|
||||
</td>
|
||||
<td><input name="start_new" type="datetime-local" class="form-control" value="{{ i.start }}" disabled="true"/></td>
|
||||
<td><input name="role_new" type="text" class="form-control" value="{{ i.role }}" disabled="true"/></td>
|
||||
<td><input name="end_new" type="datetime-local" class="form-control" value="{{ i.end }}" disabled="true" /></td>
|
||||
<td><button class="btn btn-danger" data-id='{{crew.pk}}' data-action='delete' data-target='#crewmember'><span class="fas fa-times"></span></button</td>
|
||||
</tr>
|
||||
{% for crew in object.crew.all %}
|
||||
<tr id="crew_{{crew.pk}}">
|
||||
<td>
|
||||
<select name="crewmember_{{crew.pk}}" class="form-control selectpicker" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials">
|
||||
{% if crew.crewmember != '' %}
|
||||
<option value="{{crew.crewmember.pk}}" selected="selected">{{ crew.crewmember.name }}</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
</td>
|
||||
<td><input name="start_{{crew.pk}}" type="datetime-local" class="form-control" value="{{ crew.start|date:'Y-m-d' }}T{{ crew.start|date:'H:i:s' }}"/></td>
|
||||
<td><input name="role_{{crew.pk}}" type="text" class="form-control" value="{{ crew.role }}"/></td>
|
||||
<td><input name="end_{{crew.pk}}" type="datetime-local" class="form-control" value="{{ crew.end|date:'Y-m-d' }}T{{ crew.end|date:'H:i:s' }}"/></td>
|
||||
<td><button class="btn btn-danger" data-id='{{crew.pk}}' data-action='delete' data-target='#crewmember'><span class="fas fa-times"></span></button</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="text-right">
|
||||
<button class="btn btn-secondary"><span class="fas fa-plus"></span> Add Crewmember</button>
|
||||
<button class="btn btn-secondary" data-action='add' data-target='#crewmemberst' data-clone='#crew_new'><span class="fas fa-plus"></span> Add Crewmember</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
<h4 class="col-sm-12 pb-3">Welcome back {{ user.get_full_name }}, there {%if rig_count == 1 %}is one rig coming up{%else%}are {{ rig_count|apnumber }} rigs coming up.{%endif%}</h4>
|
||||
<div class="col-sm">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="list-group-item-heading">Rigboard</h4>
|
||||
</div>
|
||||
<h4 class="card-header">Rigboard</h4>
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'rigboard' %}"><i class="fas fa-list"></i> Rigboard</a>
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'web_calendar' %}"><i class="fas fa-calendar"></i> Calendar</a>
|
||||
@@ -19,9 +17,7 @@
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'event_create' %}"><i class="fas fa-plus"></i> New Event</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-header">
|
||||
<h4 class="list-group-item-heading">Asset Database</h4>
|
||||
</div>
|
||||
<h4 class="card-header">Asset Database</h4>
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'asset_index' %}"><i class="fas fa-tag"></i> Asset List </a>
|
||||
{% if perms.assets.add_asset %}
|
||||
@@ -32,9 +28,7 @@
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'supplier_create' %}"><i class="fas fa-plus"></i> New Supplier</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-header">
|
||||
<h4 class="list-group-item-heading">Quick Links</h4>
|
||||
</div>
|
||||
<h4 class="card-header">Quick Links</h4>
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action" href="https://forum.nottinghamtec.co.uk" target="_blank" rel="noopener noreferrer"><i class="fas fa-comment-alt"></i> TEC Forum</a>
|
||||
<a class="list-group-item list-group-item-action" href="//members.nottinghamtec.co.uk/wiki" target="_blank" rel="noopener noreferrer"><i class="fas fa-pen-square"></i> TEC Wiki</a>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
{% if version.changes.anything_changed or version.changes.old == None %}
|
||||
{% for change in version.changes.field_changes %}
|
||||
<span title="Changes to {{ change.field.verbose_name }}" class="badge badge-info p-2" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}{% include "version_changes_change.html" %}{% endspaceless %}'>{{ change.field.verbose_name }}</span>
|
||||
<span title="Changes to {{ change.field.verbose_name }}" class="badge badge-info p-2" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}{% include "partials/version_changes_change.html" %}{% endspaceless %}'>{{ change.field.verbose_name }}</span>
|
||||
{% endfor %}
|
||||
{% for itemChange in version.changes.item_changes %}
|
||||
<span title="Changes to item '{% if itemChange.new %}{{ itemChange.new.name }}{% else %}{{ itemChange.old.name }}{% endif %}'" class="badge badge-info p-1" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}
|
||||
<ul class="list-group">
|
||||
{% for change in itemChange.field_changes %}
|
||||
{% for itemchange in version.changes.item_changes %}
|
||||
<span title="Changes to {{ itemchange.name }}" class="badge badge-info p-2" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}
|
||||
<ul class="list-group list-group-flush">
|
||||
{% for change in itemchange.field_changes %}
|
||||
<li class="list-group-item">
|
||||
<h4 class="list-group-item-heading">{{ change.field.verbose_name }}</h4>
|
||||
<div class="dont-break-out">{% include 'version_changes_change.html' with change=itemChange %}</div>
|
||||
<p>{{ change.field.verbose_name|title }}:</p>
|
||||
<div class="dont-break-out">{% include 'partials/version_changes_change.html' with change=itemchange %}</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endspaceless %}'>item '{% if itemChange.new %}{{ itemChange.new.name }}{% else %}{{ itemChange.old.name }}{% endif %}'</span>
|
||||
{% endspaceless %}'>{{ itemchange.name }}</span>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
nothing useful
|
||||
|
||||
@@ -118,30 +118,34 @@ class ModelComparison(object):
|
||||
@cached_property
|
||||
def item_changes(self):
|
||||
# Recieves two event version objects and compares their items, returns an array of ItemCompare objects
|
||||
item_type = ContentType.objects.get_for_model(models.EventItem)
|
||||
item_dict = {}
|
||||
if hasattr(self.version, 'parent'):
|
||||
old_item_versions = self.version.parent.revision.version_set.filter(content_type=item_type)
|
||||
new_item_versions = self.version.revision.version_set.filter(content_type=item_type)
|
||||
item_type = ContentType.objects.get_for_model(self.version.object)
|
||||
old_item_versions = self.version.parent.revision.version_set.exclude(content_type=item_type)
|
||||
new_item_versions = self.version.revision.version_set.exclude(content_type=item_type)
|
||||
|
||||
comparisonParams = {'excluded_keys': ['id', 'event', 'order']}
|
||||
comparisonParams = {'excluded_keys': ['id', 'event', 'order']}
|
||||
|
||||
# Build some dicts of what we have
|
||||
# build a list of items, key is the item_pk
|
||||
for version in old_item_versions: # put all the old versions in a list
|
||||
if version.field_dict["event_id"] == int(self.new.pk):
|
||||
compare = ModelComparison(old=version._object_version.object, **comparisonParams)
|
||||
item_dict[version.object_id] = compare
|
||||
# Build some dicts of what we have
|
||||
item_dict = {} # build a list of items, key is the item_pk
|
||||
# FIXME Removing the if checks makes things REALLY slow...
|
||||
for version in old_item_versions: # put all the old versions in a list
|
||||
#if version.field_dict["event_id"] == int(self.new.pk):
|
||||
compare = ModelComparison(old=version._object_version.object, **comparisonParams)
|
||||
item_dict[version.object_id] = compare
|
||||
|
||||
for version in new_item_versions: # go through the new versions
|
||||
if version.field_dict["event_id"] == int(self.new.pk):
|
||||
try:
|
||||
compare = item_dict[version.object_id] # see if there's a matching old version
|
||||
compare.new = version._object_version.object # then add the new version to the dictionary
|
||||
except KeyError: # there's no matching old version, so add this item to the dictionary by itself
|
||||
compare = ModelComparison(new=version._object_version.object, **comparisonParams)
|
||||
for version in new_item_versions: # go through the new versions
|
||||
#if version.field_dict["event_id"] == int(self.new.pk):
|
||||
try:
|
||||
compare = item_dict[version.object_id] # see if there's a matching old version
|
||||
compare.new = version._object_version.object # then add the new version to the dictionary
|
||||
except KeyError: # there's no matching old version, so add this item to the dictionary by itself
|
||||
compare = ModelComparison(new=version._object_version.object, **comparisonParams)
|
||||
|
||||
item_dict[version.object_id] = compare # update the dictionary with the changes
|
||||
if compare.new:
|
||||
compare.name = str(compare.new)
|
||||
else:
|
||||
compare.name = str(compare.old)
|
||||
|
||||
item_dict[version.object_id] = compare # update the dictionary with the changes
|
||||
|
||||
changes = []
|
||||
for (_, compare) in list(item_dict.items()):
|
||||
@@ -160,7 +164,6 @@ class ModelComparison(object):
|
||||
|
||||
|
||||
class RIGSVersionManager(VersionQuerySet):
|
||||
# TODO Rework this so its possible to define from the other apps
|
||||
def get_for_multiple_models(self, model_array):
|
||||
content_types = []
|
||||
for model in model_array:
|
||||
|
||||
Reference in New Issue
Block a user