Added list accounts changelist actions and display HTML emails on mailer
This commit is contained in:
parent
708758880d
commit
7d1e4d1451
2
TODO.md
2
TODO.md
|
@ -427,3 +427,5 @@ Case
|
|||
# bill changelist: dates: (closed_on, created_on, updated_on)
|
||||
|
||||
# Resource data inline show info: link to monitor data, and history chart: link to monitor data of each item
|
||||
|
||||
# DIsplay message email content nicelly
|
||||
|
|
|
@ -18,7 +18,7 @@ from . import settings
|
|||
|
||||
|
||||
def list_contacts(modeladmin, request, queryset):
|
||||
ids = queryset.values_list('id', flat=True)
|
||||
ids = queryset.order_by().values_list('id', flat=True).distinct()
|
||||
if not ids:
|
||||
messages.warning(request, "Select at least one account.")
|
||||
return
|
||||
|
@ -28,6 +28,17 @@ def list_contacts(modeladmin, request, queryset):
|
|||
list_contacts.short_description = _("List contacts")
|
||||
|
||||
|
||||
def list_accounts(modeladmin, request, queryset):
|
||||
accounts = queryset.order_by().values_list('account_id', flat=True).distinct()
|
||||
if not accounts:
|
||||
messages.warning(request, "Select at least one instance.")
|
||||
return
|
||||
url = reverse('admin:contacts_contact_changelist')
|
||||
url += '?id__in=%s' % ','.join(map(str, accounts))
|
||||
return redirect(url)
|
||||
list_accounts.short_description = _("List accounts")
|
||||
|
||||
|
||||
def service_report(modeladmin, request, queryset):
|
||||
# TODO resources
|
||||
accounts = []
|
||||
|
|
|
@ -13,6 +13,7 @@ from django.shortcuts import redirect
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import admin_date, insertattr, admin_link
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin, AccountAdmin
|
||||
from orchestra.forms.widgets import paddingCheckboxSelectMultiple
|
||||
|
||||
|
@ -212,7 +213,7 @@ class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
actions = [
|
||||
actions.manage_lines, actions.download_bills, actions.close_bills, actions.send_bills,
|
||||
actions.amend_bills, actions.bill_report, actions.service_report,
|
||||
actions.close_send_download_bills,
|
||||
actions.close_send_download_bills, list_accounts,
|
||||
]
|
||||
change_readonly_fields = ('account_link', 'type', 'is_open', 'amend_of_link', 'amend_links')
|
||||
readonly_fields = ('number', 'display_total', 'is_sent', 'display_payment_state')
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from orchestra.admin import AtLeastOneRequiredInlineFormSet, ExtendedModelAdmin
|
||||
from orchestra.admin.actions import SendEmail
|
||||
from orchestra.admin.utils import insertattr, change_url
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdmin, AccountAdminMixin
|
||||
from orchestra.forms.widgets import paddingCheckboxSelectMultiple
|
||||
|
||||
|
@ -59,7 +60,7 @@ class ContactAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
'fields': ('address', ('zipcode', 'city'), 'country')
|
||||
}),
|
||||
)
|
||||
actions = [SendEmail(),]
|
||||
actions = (SendEmail(), list_accounts)
|
||||
|
||||
def dispaly_name(self, contact):
|
||||
return str(contact)
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||
from orchestra.admin.utils import change_url
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
||||
|
||||
from .forms import DatabaseCreationForm, DatabaseUserChangeForm, DatabaseUserCreationForm
|
||||
|
@ -42,6 +43,7 @@ class DatabaseAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
filter_horizontal = ['users']
|
||||
filter_by_account_fields = ('users',)
|
||||
list_prefetch_related = ('users',)
|
||||
actions = (list_accounts,)
|
||||
|
||||
def display_users(self, db):
|
||||
links = []
|
||||
|
@ -90,6 +92,7 @@ class DatabaseUserAdmin(SelectAccountAdminMixin, ChangePasswordAdminMixin, Exten
|
|||
readonly_fields = ('account_link', 'display_databases',)
|
||||
filter_by_account_fields = ('databases',)
|
||||
list_prefetch_related = ('databases',)
|
||||
actions = (list_accounts,)
|
||||
|
||||
def display_databases(self, user):
|
||||
links = []
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import admin_link, change_url
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||
from orchestra.utils import apps
|
||||
|
||||
|
@ -57,7 +58,7 @@ class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
change_readonly_fields = ('name', 'serial')
|
||||
search_fields = ('name', 'account__username')
|
||||
add_form = BatchDomainCreationAdminForm
|
||||
actions = (edit_records, set_soa)
|
||||
actions = (edit_records, set_soa, list_accounts)
|
||||
change_view_actions = (view_zone, edit_records)
|
||||
|
||||
top_link = admin_link('top')
|
||||
|
|
|
@ -80,15 +80,15 @@ class ValidateZoneMixin(object):
|
|||
def clean(self):
|
||||
""" Checks if everything is consistent """
|
||||
super(ValidateZoneMixin, self).clean()
|
||||
if any(formset.errors):
|
||||
if any(self.errors):
|
||||
return
|
||||
if formset.instance.name:
|
||||
if self.instance.name:
|
||||
records = []
|
||||
for form in formset.forms:
|
||||
for form in self.forms:
|
||||
data = form.cleaned_data
|
||||
if data and not data['DELETE']:
|
||||
records.append(data)
|
||||
domain = domain_for_validation(formset.instance, records)
|
||||
domain = domain_for_validation(self.instance, records)
|
||||
validators.validate_zone(domain.render_zone())
|
||||
|
||||
|
||||
|
|
|
@ -273,14 +273,14 @@ class Record(models.Model):
|
|||
)
|
||||
|
||||
VALIDATORS = {
|
||||
MX: validators.validate_mx_record,
|
||||
NS: validators.validate_zone_label,
|
||||
A: validate_ipv4_address,
|
||||
AAAA: validate_ipv6_address,
|
||||
CNAME: validators.validate_zone_label,
|
||||
TXT: validate_ascii,
|
||||
SRV: validators.validate_srv_record,
|
||||
SOA: validators.validate_soa_record,
|
||||
MX: (validators.validate_mx_record,),
|
||||
NS: (validators.validate_zone_label,),
|
||||
A: (validate_ipv4_address,),
|
||||
AAAA: (validate_ipv6_address,),
|
||||
CNAME: (validators.validate_zone_label,),
|
||||
TXT: (validate_ascii, validators.validate_quoted_record),
|
||||
SRV: (validators.validate_srv_record,),
|
||||
SOA: (validators.validate_soa_record,),
|
||||
}
|
||||
|
||||
domain = models.ForeignKey(Domain, verbose_name=_("domain"), related_name='records')
|
||||
|
@ -300,8 +300,9 @@ class Record(models.Model):
|
|||
if self.type != self.TXT:
|
||||
self.value = self.value.lower().strip()
|
||||
if self.type:
|
||||
for validator in self.VALIDATORS.get(self.type, []):
|
||||
try:
|
||||
self.VALIDATORS[self.type](self.value)
|
||||
validator(self.value)
|
||||
except ValidationError as error:
|
||||
raise ValidationError({
|
||||
'value': error,
|
||||
|
|
|
@ -107,6 +107,16 @@ def validate_soa_record(value):
|
|||
raise ValidationError(msg)
|
||||
|
||||
|
||||
def validate_quoted_record(value):
|
||||
value = value.strip()
|
||||
if ' ' in value and (value[0] != '"' or value[-1] != '"'):
|
||||
raise ValidationError(
|
||||
_("This record value contains spaces, you must enclose the string in double quotes; "
|
||||
"otherwise, individual words will be separately quoted and break up the record "
|
||||
"into multiple parts.")
|
||||
)
|
||||
|
||||
|
||||
def validate_zone(zone):
|
||||
""" Ultimate zone file validation using named-checkzone """
|
||||
zone_name = zone.split()[0][:-1]
|
||||
|
|
|
@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||
from orchestra.admin.actions import disable
|
||||
from orchestra.admin.utils import admin_link
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
||||
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
||||
|
||||
|
@ -53,7 +54,7 @@ class ListAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedModel
|
|||
add_form = ListCreationForm
|
||||
list_select_related = ('account', 'address_domain',)
|
||||
filter_by_account_fields = ['address_domain']
|
||||
actions = (disable,)
|
||||
actions = (disable, list_accounts)
|
||||
|
||||
address_domain_link = admin_link('address_domain', order='address_domain__name')
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||
from orchestra.admin.actions import disable
|
||||
from orchestra.admin.utils import admin_link, change_url
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
||||
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
||||
|
||||
|
@ -69,7 +70,7 @@ class MailboxAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedMo
|
|||
add_form = MailboxCreationForm
|
||||
form = MailboxChangeForm
|
||||
list_prefetch_related = ('addresses__domain',)
|
||||
actions = (disable,)
|
||||
actions = (disable, list_accounts)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(MailboxAdmin, self).__init__(*args, **kwargs)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import base64
|
||||
import email
|
||||
|
||||
from django import forms
|
||||
from django.contrib import admin
|
||||
from django.core.urlresolvers import reverse
|
||||
|
@ -29,6 +32,21 @@ class MessageAdmin(admin.ModelAdmin):
|
|||
)
|
||||
list_filter = ('state', 'priority', 'retries')
|
||||
list_prefetch_related = ('logs__id')
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': ('state', 'priority', ('retries', 'last_retry_delta'),
|
||||
'display_full_subject', 'display_to_address', 'display_from_address',
|
||||
'display_content'),
|
||||
}),
|
||||
(_("Edit"), {
|
||||
'classes': ('collapse',),
|
||||
'fields': ('subject', 'to_address', 'from_address', 'content'),
|
||||
}),
|
||||
)
|
||||
readonly_fields = (
|
||||
'retries', 'last_retry_delta', 'display_full_subject', 'display_to_address',
|
||||
'display_from_address', 'display_content',
|
||||
)
|
||||
|
||||
colored_state = admin_colored('state', colors=COLORS)
|
||||
created_at_delta = admin_date('created_at')
|
||||
|
@ -52,6 +70,37 @@ class MessageAdmin(admin.ModelAdmin):
|
|||
num_logs.admin_order_field = 'logs__count'
|
||||
num_logs.allow_tags = True
|
||||
|
||||
def display_content(self, instance):
|
||||
part = email.message_from_string(instance.content)
|
||||
payload = part.get_payload()
|
||||
if isinstance(payload, list):
|
||||
for part in payload:
|
||||
payload = part.get_payload()
|
||||
if part.get_content_type() == 'text/html':
|
||||
# prioritize HTML
|
||||
payload = '<div style="padding-left:110px">%s</div>' % payload
|
||||
break
|
||||
if part.get('Content-Transfer-Encoding') == 'base64':
|
||||
payload = base64.b64decode(payload)
|
||||
payload = payload.decode(part.get_charsets()[0])
|
||||
if part.get_content_type() == 'text/plain':
|
||||
payload = payload.replace('\n', '<br>')
|
||||
return payload
|
||||
display_content.short_description = _("Content")
|
||||
display_content.allow_tags = True
|
||||
|
||||
def display_full_subject(self, instance):
|
||||
return instance.subject
|
||||
display_full_subject.short_description = _("Subject")
|
||||
|
||||
def display_from_address(self, instance):
|
||||
return instance.from_address
|
||||
display_from_address.short_description = _("From address")
|
||||
|
||||
def display_to_address(self, instance):
|
||||
return instance.to_address
|
||||
display_to_address.short_description = _("To address")
|
||||
|
||||
def get_urls(self):
|
||||
from django.conf.urls import url
|
||||
urls = super(MessageAdmin, self).get_urls()
|
||||
|
@ -77,6 +126,7 @@ class MessageAdmin(admin.ModelAdmin):
|
|||
kwargs['widget'] = forms.TextInput(attrs={'size':'100'})
|
||||
return super(MessageAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
|
||||
|
||||
class SMTPLogAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'id', 'message_link', 'colored_result', 'date_delta', 'log_message'
|
||||
|
|
|
@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import admin_link, admin_date, change_url
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||
from orchestra.utils.humanize import naturaldate
|
||||
|
||||
|
@ -49,13 +50,18 @@ class MetricStorageInline(admin.TabularInline):
|
|||
class OrderAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||
list_display = (
|
||||
'id', 'service_link', 'account_link', 'content_object_link',
|
||||
'display_registered_on', 'display_billed_until', 'display_cancelled_on', 'display_metric'
|
||||
'display_registered_on', 'display_billed_until', 'display_cancelled_on',
|
||||
'display_metric'
|
||||
)
|
||||
list_filter = (
|
||||
ActiveOrderListFilter, IgnoreOrderListFilter, BilledOrderListFilter, 'service'
|
||||
)
|
||||
list_filter = (ActiveOrderListFilter, IgnoreOrderListFilter, BilledOrderListFilter, 'service')
|
||||
default_changelist_filters = (
|
||||
('ignore', '0'),
|
||||
)
|
||||
actions = (BillSelectedOrders(), mark_as_ignored, mark_as_not_ignored, report)
|
||||
actions = (
|
||||
BillSelectedOrders(), mark_as_ignored, mark_as_not_ignored, report, list_accounts
|
||||
)
|
||||
change_view_actions = (BillSelectedOrders(), mark_as_ignored, mark_as_not_ignored)
|
||||
date_hierarchy = 'registered_on'
|
||||
inlines = (MetricStorageInline,)
|
||||
|
@ -111,7 +117,9 @@ class OrderAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
display_billed_until.admin_order_field = 'billed_until'
|
||||
|
||||
def display_metric(self, order):
|
||||
""" dispalys latest metric value, don't uses latest() because not loosing prefetch_related """
|
||||
"""
|
||||
dispalys latest metric value, don't uses latest() because not loosing prefetch_related
|
||||
"""
|
||||
try:
|
||||
metric = order.metrics.all()[0]
|
||||
except IndexError:
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from orchestra.admin import ChangeViewActionsMixin, ExtendedModelAdmin
|
||||
from orchestra.admin.utils import admin_colored, admin_link
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
|
||||
from orchestra.plugins.admin import SelectPluginAdminMixin
|
||||
|
||||
|
@ -91,7 +92,7 @@ class TransactionAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
actions.process_transactions, actions.mark_as_executed, actions.mark_as_secured,
|
||||
actions.mark_as_rejected,
|
||||
)
|
||||
actions = change_view_actions + (actions.report,)
|
||||
actions = change_view_actions + (actions.report, list_accounts)
|
||||
filter_by_account_fields = ('bill', 'source')
|
||||
change_readonly_fields = ('amount', 'currency')
|
||||
readonly_fields = (
|
||||
|
|
|
@ -2,6 +2,7 @@ from django.contrib import admin
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import insertattr
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||
from orchestra.contrib.services.models import Service
|
||||
|
||||
|
@ -29,6 +30,7 @@ class ContractedPlanAdmin(AccountAdminMixin, admin.ModelAdmin):
|
|||
list_filter = ('plan__name',)
|
||||
list_select_related = ('plan', 'account')
|
||||
search_fields = ('account__username', 'plan__name', 'id')
|
||||
actions = (list_accounts,)
|
||||
|
||||
|
||||
admin.site.register(Plan, PlanAdmin)
|
||||
|
|
|
@ -3,6 +3,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||
from orchestra.admin.actions import disable
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||
from orchestra.plugins.admin import SelectPluginAdminMixin
|
||||
|
||||
|
@ -18,7 +19,7 @@ class SaaSAdmin(SelectPluginAdminMixin, ChangePasswordAdminMixin, AccountAdminMi
|
|||
plugin = SoftwareService
|
||||
plugin_field = 'service'
|
||||
plugin_title = 'Software as a Service'
|
||||
actions = (disable,)
|
||||
actions = (disable, list_accounts)
|
||||
|
||||
def display_site_domain(self, saas):
|
||||
site_domain = saas.get_site_domain()
|
||||
|
|
|
@ -14,7 +14,8 @@ from .. import settings
|
|||
class PhpListSaaSBackend(ServiceController):
|
||||
"""
|
||||
Creates a new phplist instance on a phpList multisite installation.
|
||||
The site is created by means of creating a new database per phpList site, but all sites share the same code.
|
||||
The site is created by means of creating a new database per phpList site,
|
||||
but all sites share the same code.
|
||||
|
||||
<tt>// config/config.php
|
||||
$site = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
|
||||
|
@ -28,7 +29,8 @@ class PhpListSaaSBackend(ServiceController):
|
|||
def _save(self, saas, server):
|
||||
admin_link = 'https://%s/admin/' % saas.get_site_domain()
|
||||
print('admin_link:', admin_link)
|
||||
admin_content = requests.get(admin_link, verify=settings.SAAS_PHPLIST_VERIFY_SSL).content.decode('utf8')
|
||||
admin_content = requests.get(admin_link, verify=settings.SAAS_PHPLIST_VERIFY_SSL)
|
||||
admin_content = admin_content.content.decode('utf8')
|
||||
if admin_content.startswith('Cannot connect to Database'):
|
||||
raise RuntimeError("Database is not yet configured")
|
||||
install = re.search(r'([^"]+firstinstall[^"]+)', admin_content)
|
||||
|
@ -68,7 +70,7 @@ class PhpListSaaSBackend(ServiceController):
|
|||
--execute='UPDATE phplist_admin SET password="%(digest)s" where ID=1; \\
|
||||
UPDATE phplist_user_user SET password="%(digest)s" where ID=1;' \\
|
||||
%(db_name)s""") % context
|
||||
print(cmd)
|
||||
print('cmd:', cmd)
|
||||
sshrun(server.get_address(), cmd)
|
||||
|
||||
def save(self, saas):
|
||||
|
|
|
@ -3,6 +3,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
|
||||
from orchestra.admin.actions import disable
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import SelectAccountAdminMixin
|
||||
from orchestra.contrib.accounts.filters import IsActiveListFilter
|
||||
|
||||
|
@ -42,7 +43,7 @@ class SystemUserAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, Extende
|
|||
form = SystemUserChangeForm
|
||||
ordering = ('-id',)
|
||||
change_view_actions = (set_permission, disable)
|
||||
actions = (delete_selected,) + change_view_actions
|
||||
actions = (delete_selected, list_accounts) + change_view_actions
|
||||
|
||||
def display_main(self, user):
|
||||
return user.is_main
|
||||
|
|
|
@ -4,6 +4,7 @@ from django.contrib.auth.admin import UserAdmin
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||
|
||||
from .forms import VPSChangeForm, VPSCreationForm
|
||||
|
@ -37,6 +38,7 @@ class VPSAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
'fields': ('password1', 'password2',)
|
||||
}),
|
||||
)
|
||||
actions = (list_accounts,)
|
||||
|
||||
def get_urls(self):
|
||||
useradmin = UserAdmin(VPS, self.admin_site)
|
||||
|
|
|
@ -6,6 +6,7 @@ from django.utils.translation import ugettext, ugettext_lazy as _
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import change_url, get_modeladmin
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||
from orchestra.forms.widgets import DynamicHelpTextSelect
|
||||
from orchestra.plugins.admin import SelectPluginAdminMixin
|
||||
|
@ -58,6 +59,7 @@ class WebAppAdmin(SelectPluginAdminMixin, AccountAdminMixin, ExtendedModelAdmin)
|
|||
plugin = AppType
|
||||
plugin_field = 'type'
|
||||
plugin_title = _("Web application type")
|
||||
actions = (list_accounts,)
|
||||
|
||||
def display_websites(self, webapp):
|
||||
websites = []
|
||||
|
|
|
@ -5,10 +5,10 @@ from django.db.models import Q
|
|||
from django.utils.encoding import force_text
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.actions import disable
|
||||
from orchestra.admin.utils import admin_link, change_url
|
||||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin, SelectAccountAdminMixin
|
||||
from orchestra.forms.widgets import DynamicHelpTextSelect
|
||||
|
||||
|
@ -69,7 +69,7 @@ class WebsiteAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
filter_by_account_fields = ['domains']
|
||||
list_prefetch_related = ('domains', 'content_set__webapp')
|
||||
search_fields = ('name', 'account__username', 'domains__name', 'content__webapp__name')
|
||||
actions = (disable,)
|
||||
actions = (disable, list_accounts)
|
||||
|
||||
def display_domains(self, website):
|
||||
domains = []
|
||||
|
|
Loading…
Reference in a new issue