Fixed up models & forms

This commit is contained in:
Jeremy Stretch 2019-03-12 10:15:56 -04:00
parent 5b753923b6
commit 3b9c0e4c67
8 changed files with 140 additions and 30 deletions

View File

@ -3163,7 +3163,7 @@ class VirtualChassisFilterForm(BootstrapMixin, CustomFieldFilterForm):
# #
class PowerPanelForm(BootstrapMixin, forms.ModelForm): class PowerPanelForm(BootstrapMixin, forms.ModelForm):
rackgroup = ChainedModelChoiceField( rack_group = ChainedModelChoiceField(
queryset=RackGroup.objects.all(), queryset=RackGroup.objects.all(),
chains=( chains=(
('site', 'site'), ('site', 'site'),
@ -3177,7 +3177,7 @@ class PowerPanelForm(BootstrapMixin, forms.ModelForm):
class Meta: class Meta:
model = PowerPanel model = PowerPanel
fields = [ fields = [
'site', 'rackgroup', 'name', 'site', 'rack_group', 'name',
] ]
widgets = { widgets = {
'site': APISelect( 'site': APISelect(
@ -3198,7 +3198,7 @@ class PowerPanelCSVForm(forms.ModelForm):
'invalid_choice': 'Site not found.', 'invalid_choice': 'Site not found.',
} }
) )
group_name = forms.CharField( rackgroup_name = forms.CharField(
help_text='Name of rack group', help_text='Name of rack group',
required=False required=False
) )
@ -3213,6 +3213,17 @@ class PowerPanelCSVForm(forms.ModelForm):
# #
class PowerFeedForm(BootstrapMixin, CustomFieldForm): class PowerFeedForm(BootstrapMixin, CustomFieldForm):
site = ChainedModelChoiceField(
queryset=Site.objects.all(),
required=False,
widget=APISelect(
api_url='/api/dcim/sites/',
filter_for={
'power_panel': 'site_id',
'rack': 'site_id',
}
)
)
tags = TagField( tags = TagField(
required=False required=False
) )
@ -3220,15 +3231,15 @@ class PowerFeedForm(BootstrapMixin, CustomFieldForm):
class Meta: class Meta:
model = PowerFeed model = PowerFeed
fields = [ fields = [
'powerpanel', 'rack', 'name', 'type', 'status', 'supply', 'voltage', 'amperage', 'phase', 'max_utilization', 'site', 'power_panel', 'rack', 'name', 'type', 'status', 'supply', 'voltage', 'amperage', 'phase',
'comments', 'tags', 'max_utilization', 'comments', 'tags',
] ]
widgets = { widgets = {
'site': APISelect( 'power_panel': APISelect(
api_url="/api/dcim/sites/", api_url="/api/dcim/power-panels/"
filter_for={ ),
'rackgroup': 'site_id', 'rack': APISelect(
} api_url="/api/dcim/racks/"
), ),
'type': StaticSelect2(), 'type': StaticSelect2(),
'status': StaticSelect2(), 'status': StaticSelect2(),

View File

@ -1,4 +1,4 @@
# Generated by Django 2.1.7 on 2019-03-12 02:29 # Generated by Django 2.1.7 on 2019-03-12 14:08
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
@ -31,7 +31,7 @@ class Migration(migrations.Migration):
('comments', models.TextField(blank=True)), ('comments', models.TextField(blank=True)),
], ],
options={ options={
'ordering': ['powerpanel', 'name'], 'ordering': ['power_panel', 'name'],
}, },
), ),
migrations.CreateModel( migrations.CreateModel(
@ -41,7 +41,7 @@ class Migration(migrations.Migration):
('created', models.DateField(auto_now_add=True, null=True)), ('created', models.DateField(auto_now_add=True, null=True)),
('last_updated', models.DateTimeField(auto_now=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)),
('name', models.CharField(max_length=50)), ('name', models.CharField(max_length=50)),
('rackgroup', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.RackGroup')), ('rack_group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='dcim.RackGroup')),
('site', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='dcim.Site')), ('site', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='dcim.Site')),
], ],
options={ options={
@ -50,7 +50,7 @@ class Migration(migrations.Migration):
), ),
migrations.AddField( migrations.AddField(
model_name='powerfeed', model_name='powerfeed',
name='powerpanel', name='power_panel',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='powerfeeds', to='dcim.PowerPanel'), field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='powerfeeds', to='dcim.PowerPanel'),
), ),
migrations.AddField( migrations.AddField(
@ -69,6 +69,6 @@ class Migration(migrations.Migration):
), ),
migrations.AlterUniqueTogether( migrations.AlterUniqueTogether(
name='powerfeed', name='powerfeed',
unique_together={('powerpanel', 'name')}, unique_together={('power_panel', 'name')},
), ),
] ]

View File

@ -2682,7 +2682,7 @@ class PowerPanel(ChangeLoggedModel):
to='Site', to='Site',
on_delete=models.PROTECT on_delete=models.PROTECT
) )
rackgroup = models.ForeignKey( rack_group = models.ForeignKey(
to='RackGroup', to='RackGroup',
on_delete=models.PROTECT, on_delete=models.PROTECT,
blank=True, blank=True,
@ -2692,7 +2692,7 @@ class PowerPanel(ChangeLoggedModel):
max_length=50 max_length=50
) )
csv_headers = ['site', 'rackgroup', 'name'] csv_headers = ['site', 'rack_group', 'name']
class Meta: class Meta:
ordering = ['site', 'name'] ordering = ['site', 'name']
@ -2707,7 +2707,7 @@ class PowerPanel(ChangeLoggedModel):
def to_csv(self): def to_csv(self):
return ( return (
self.site.name, self.site.name,
self.rackgroup.name if self.rackgroup else None, self.rack_group.name if self.rack_group else None,
self.name, self.name,
) )
@ -2716,7 +2716,7 @@ class PowerFeed(ChangeLoggedModel, CustomFieldModel):
""" """
An electrical circuit delivered from a PowerPanel. An electrical circuit delivered from a PowerPanel.
""" """
powerpanel = models.ForeignKey( power_panel = models.ForeignKey(
to='PowerPanel', to='PowerPanel',
on_delete=models.PROTECT, on_delete=models.PROTECT,
related_name='powerfeeds' related_name='powerfeeds'
@ -2771,13 +2771,13 @@ class PowerFeed(ChangeLoggedModel, CustomFieldModel):
tags = TaggableManager(through=TaggedItem) tags = TaggableManager(through=TaggedItem)
csv_headers = [ csv_headers = [
'powerpanel', 'rack', 'name', 'type', 'status', 'supply', 'voltage', 'amperage', 'phase', 'max_utilization', 'power_panel', 'rack', 'name', 'type', 'status', 'supply', 'voltage', 'amperage', 'phase', 'max_utilization',
'comments', 'comments',
] ]
class Meta: class Meta:
ordering = ['powerpanel', 'name'] ordering = ['power_panel', 'name']
unique_together = ['powerpanel', 'name'] unique_together = ['power_panel', 'name']
def __str__(self): def __str__(self):
return self.name return self.name
@ -2787,7 +2787,7 @@ class PowerFeed(ChangeLoggedModel, CustomFieldModel):
def to_csv(self): def to_csv(self):
return ( return (
self.powerpanel.name, self.power_panel.name,
self.rack.name if self.rack else None, self.rack.name if self.rack else None,
self.name, self.name,
self.get_type_display(), self.get_type_display(),

View File

@ -285,7 +285,9 @@ urlpatterns = [
url(r'^power-panels/add/$', views.PowerPanelCreateView.as_view(), name='powerpanel_add'), url(r'^power-panels/add/$', views.PowerPanelCreateView.as_view(), name='powerpanel_add'),
url(r'^power-panels/import/$', views.PowerPanelBulkImportView.as_view(), name='powerpanel_import'), url(r'^power-panels/import/$', views.PowerPanelBulkImportView.as_view(), name='powerpanel_import'),
url(r'^power-panels/delete/$', views.PowerPanelBulkDeleteView.as_view(), name='powerpanel_bulk_delete'), url(r'^power-panels/delete/$', views.PowerPanelBulkDeleteView.as_view(), name='powerpanel_bulk_delete'),
url(r'^power-panels/(?P<pk>\d+)/$', views.PowerPanelView.as_view(), name='powerpanel'),
url(r'^power-panels/(?P<pk>\d+)/edit/$', views.PowerPanelEditView.as_view(), name='powerpanel_edit'), url(r'^power-panels/(?P<pk>\d+)/edit/$', views.PowerPanelEditView.as_view(), name='powerpanel_edit'),
url(r'^power-panels/(?P<pk>\d+)/delete/$', views.PowerPanelDeleteView.as_view(), name='powerpanel_delete'),
url(r'^power-panels/(?P<pk>\d+)/changelog/$', ObjectChangeLogView.as_view(), name='powerpanel_changelog', kwargs={'model': PowerPanel}), url(r'^power-panels/(?P<pk>\d+)/changelog/$', ObjectChangeLogView.as_view(), name='powerpanel_changelog', kwargs={'model': PowerPanel}),
# Racks # Racks

View File

@ -2131,6 +2131,17 @@ class PowerPanelListView(ObjectListView):
template_name = 'dcim/powerpanel_list.html' template_name = 'dcim/powerpanel_list.html'
class PowerPanelView(View):
def get(self, request, pk):
powerpanel = get_object_or_404(PowerPanel.objects.select_related('site', 'rack_group'), pk=pk)
return render(request, 'dcim/powerpanel.html', {
'powerpanel': powerpanel,
})
class PowerPanelCreateView(PermissionRequiredMixin, ObjectEditView): class PowerPanelCreateView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'dcim.add_powerpanel' permission_required = 'dcim.add_powerpanel'
model = PowerPanel model = PowerPanel
@ -2142,6 +2153,12 @@ class PowerPanelEditView(PowerPanelCreateView):
permission_required = 'dcim.change_powerpanel' permission_required = 'dcim.change_powerpanel'
class PowerPanelDeleteView(PermissionRequiredMixin, ObjectDeleteView):
permission_required = 'dcim.delete_powerpanel'
model = PowerPanel
default_return_url = 'dcim:powerpanel_list'
class PowerPanelBulkImportView(PermissionRequiredMixin, BulkImportView): class PowerPanelBulkImportView(PermissionRequiredMixin, BulkImportView):
permission_required = 'dcim.add_powerpanel' permission_required = 'dcim.add_powerpanel'
model_form = forms.PowerPanelCSVForm model_form = forms.PowerPanelCSVForm
@ -2178,7 +2195,7 @@ class PowerFeedView(View):
def get(self, request, pk): def get(self, request, pk):
powerfeed = get_object_or_404(PowerFeed.objects.select_related('panel', 'rack'), pk=pk) powerfeed = get_object_or_404(PowerFeed.objects.select_related('power_panel', 'rack'), pk=pk)
return render(request, 'dcim/powerfeed.html', { return render(request, 'dcim/powerfeed.html', {
'powerfeed': powerfeed, 'powerfeed': powerfeed,

View File

@ -8,11 +8,11 @@
<div class="col-sm-8 col-md-9"> <div class="col-sm-8 col-md-9">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li><a href="{% url 'dcim:powerfeed_list' %}">Power Feeds</a></li> <li><a href="{% url 'dcim:powerfeed_list' %}">Power Feeds</a></li>
<li><a href="{{ powerfeed.site.get_absolute_url }}">{{ powerfeed.site }}</a></li> <li><a href="{{ powerfeed.power_panel.get_absolute_url }}">{{ powerfeed.power_panel }}</a></li>
{% if powerfeed.rackgroup %} {% if powerfeed.rack %}
<li><a href="{{ powerfeed.rackgroup.get_absolute_url }}">{{ powerfeed.rackgroup }}</a></li> <li><a href="{{ powerfeed.rack.get_absolute_url }}">{{ powerfeed.rack }}</a></li>
{% endif %} {% endif %}
<li>{{ site }}</li> <li>{{ powerfeed }}</li>
</ol> </ol>
</div> </div>
<div class="col-sm-4 col-md-3"> <div class="col-sm-4 col-md-3">
@ -57,7 +57,7 @@
<tr> <tr>
<td>Power Panel</td> <td>Power Panel</td>
<td> <td>
<a href="{{ powerfeed.powerpanel.get_absolute_url }}">{{ powerfeed.powerpanel }}</a> <a href="{{ powerfeed.power_panel.get_absolute_url }}">{{ powerfeed.power_panel }}</a>
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@ -5,7 +5,8 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"><strong>Power Feed</strong></div> <div class="panel-heading"><strong>Power Feed</strong></div>
<div class="panel-body"> <div class="panel-body">
{% render_field form.powerpanel %} {% render_field form.site %}
{% render_field form.power_panel %}
{% render_field form.rack %} {% render_field form.rack %}
{% render_field form.name %} {% render_field form.name %}
{% render_field form.type %} {% render_field form.type %}

View File

@ -0,0 +1,79 @@
{% extends '_base.html' %}
{% load static %}
{% load tz %}
{% load helpers %}
{% block header %}
<div class="row noprint">
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'dcim:powerpanel_list' %}">Power Panels</a></li>
<li><a href="{{ powerpanel.site.get_absolute_url }}">{{ powerpanel.site }}</a></li>
{% if powerpanel.rack_group %}
<li><a href="{{ powerpanel.rack_group.get_absolute_url }}">{{ powerpanel.rack_group }}</a></li>
{% endif %}
<li>{{ powerpanel }}</li>
</ol>
</div>
<div class="col-sm-4 col-md-3">
<form action="{% url 'dcim:powerpanel_list' %}" method="get">
<div class="input-group">
<input type="text" name="q" class="form-control" placeholder="Search power panels" />
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</span>
</div>
</form>
</div>
</div>
<div class="pull-right noprint">
{% if perms.dcim.change_powerpanel %}
<a href="{% url 'dcim:powerpanel_edit' pk=powerpanel.pk %}" class="btn btn-warning">
<span class="fa fa-pencil" aria-hidden="true"></span>
Edit this power panel
</a>
{% endif %}
{% if perms.dcim.delete_powerpanel %}
<a href="{% url 'dcim:powerpanel_delete' pk=powerpanel.pk %}" class="btn btn-danger">
<span class="fa fa-trash" aria-hidden="true"></span>
Delete this power panel
</a>
{% endif %}
</div>
<h1>{% block title %}{{ powerpanel }}{% endblock %}</h1>
{% include 'inc/created_updated.html' with obj=powerpanel %}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-5">
<div class="panel panel-default">
<div class="panel-heading">
<strong>Power Panel</strong>
</div>
<table class="table table-hover panel-body attr-table">
<tr>
<td>Site</td>
<td>
<a href="{{ powerpanel.site.get_absolute_url }}">{{ powerpanel.site }}</a>
</td>
</tr>
<tr>
<td>Rack Group</td>
<td>
{% if powerpanel.rack_group %}
<a href="{{ powerpanel.rack_group.get_absolute_url }}">{{ powerpanel.rack_group }}</a>
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
</tr>
</table>
</div>
</div>
<div class="col-md-7">
</div>
</div>
{% endblock %}