mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
- When a link on 'Nearby Wi-Fi Networks' page is clicked, a new Wi-Fi connection page is shown. In this form, the DNS-over-TLS and IPv6 method radio buttons are not pre-selected with default value. Fix this by setting default values for them. Tests: - On a system with Wi-Fi device, click on 'Nearby Wi-Fi Networks', click on a Wi-Fi network and go to new Wi-Fi connection creation page. Notice that values for DNS-over-TLS and IPv6 connection method are filled in. Simply clicking 'Submit' creates the connection. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: Veiko Aasa <veiko17@disroot.org>
609 lines
22 KiB
Python
609 lines
22 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import logging
|
|
|
|
from django.contrib import messages
|
|
from django.shortcuts import redirect
|
|
from django.template.response import TemplateResponse
|
|
from django.urls import reverse_lazy
|
|
from django.utils.translation import gettext as _
|
|
from django.utils.translation import gettext_lazy
|
|
from django.views.decorators.http import require_POST
|
|
from django.views.generic.edit import FormView
|
|
|
|
from plinth import network
|
|
from plinth.modules import names, networks
|
|
from plinth.views import AppView
|
|
|
|
from .forms import (ConnectionTypeSelectForm, EthernetForm, GenericForm,
|
|
InternetConnectionTypeForm, NetworkTopologyForm, PPPoEForm,
|
|
RouterConfigurationForm, WifiForm)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# i18n for device.state
|
|
# https://developer.gnome.org/libnm/1.29/libnm-nm-dbus-interface.html#NMDeviceState
|
|
CONNECTION_METHOD_STRINGS = {
|
|
'disabled': gettext_lazy('disabled'),
|
|
'auto': gettext_lazy('automatic'),
|
|
'manual': gettext_lazy('manual'),
|
|
'shared': gettext_lazy('shared'),
|
|
'link-local': gettext_lazy('link-local'),
|
|
'dhcp': gettext_lazy('dhcp'),
|
|
'ignore': gettext_lazy('ignore'),
|
|
}
|
|
|
|
# i18n for device.state
|
|
# https://developer.gnome.org/libnm/1.29/libnm-nm-dbus-interface.html#NMDeviceState
|
|
DEVICE_STATE_STRINGS = {
|
|
'unknown': gettext_lazy('unknown'),
|
|
'unmanaged': gettext_lazy('unmanaged'),
|
|
'unavailable': gettext_lazy('unavailable'),
|
|
'disconnected': gettext_lazy('disconnected'),
|
|
'prepare': gettext_lazy('preparing'),
|
|
'config': gettext_lazy('connecting'),
|
|
'need-auth': gettext_lazy('needs authentication'),
|
|
'ip-config': gettext_lazy('requesting address'),
|
|
'ip-check': gettext_lazy('checking'),
|
|
'secondaries': gettext_lazy('waiting for secondary'),
|
|
'activated': gettext_lazy('activated'),
|
|
'deactivating': gettext_lazy('deactivating'),
|
|
'failed': gettext_lazy('failed'),
|
|
}
|
|
|
|
# i18n for device.state_reason
|
|
# https://developer.gnome.org/libnm/1.29/libnm-nm-dbus-interface.html#NMDeviceStateReason
|
|
DEVICE_STATE_REASON_STRINGS = {
|
|
'none':
|
|
gettext_lazy('no reason'),
|
|
'unknown':
|
|
gettext_lazy('unknown error'),
|
|
'now-managed':
|
|
gettext_lazy('device is now managed'),
|
|
'now-unmanaged':
|
|
gettext_lazy('device is now unmanaged'),
|
|
'config-failed':
|
|
gettext_lazy('configuration failed'),
|
|
'no-secrets':
|
|
gettext_lazy('secrets required'),
|
|
'dhcp-start-failed':
|
|
gettext_lazy('DHCP client failed to start'),
|
|
'dhcp-error':
|
|
gettext_lazy('DHCP client error'),
|
|
'dhcp-failed':
|
|
gettext_lazy('DHCP client failed'),
|
|
'shared-start-failed':
|
|
gettext_lazy('shared connection service failed to start'),
|
|
'shared-failed':
|
|
gettext_lazy('shared connection service failed'),
|
|
'removed':
|
|
gettext_lazy('device was removed'),
|
|
'user-requested':
|
|
gettext_lazy('device disconnected by user'),
|
|
'dependency-failed':
|
|
gettext_lazy('a dependency of the connection failed'),
|
|
'ssid-not-found':
|
|
gettext_lazy('Wi-Fi network not found'),
|
|
'secondary-connection-failed':
|
|
gettext_lazy('a secondary connection failed'),
|
|
'new-activation':
|
|
gettext_lazy('new connection activation was enqueued'),
|
|
'ip-address-duplicate':
|
|
gettext_lazy('a duplicate IP address was detected'),
|
|
'ip-method-unsupported':
|
|
gettext_lazy('selected IP method is not supported'),
|
|
}
|
|
|
|
# i18n for device.type
|
|
# https://developer.gnome.org/libnm/1.29/libnm-nm-dbus-interface.html#NMDeviceType
|
|
DEVICE_TYPE_STRINGS = {
|
|
'unknown': gettext_lazy('unknown'),
|
|
'ethernet': gettext_lazy('Ethernet'),
|
|
'wifi': gettext_lazy('Wi-Fi'),
|
|
'generic': gettext_lazy('generic'),
|
|
'tun': gettext_lazy('TUN or TAP interface'),
|
|
'wireguard': gettext_lazy('WireGuard'),
|
|
}
|
|
|
|
# i18n for wireless.mode
|
|
# https://developer.gnome.org/libnm/1.29/libnm-nm-dbus-interface.html#NM80211Mode
|
|
WIRELESS_MODE_STRINGS = {
|
|
'unknown': gettext_lazy('unknown'),
|
|
'adhoc': gettext_lazy('ad-hoc'),
|
|
'infra': gettext_lazy('infrastructure'),
|
|
'ap': gettext_lazy('access point'),
|
|
'mesh': gettext_lazy('mesh point'),
|
|
}
|
|
|
|
# i18n for connection.dns_over_tls
|
|
# https://networkmanager.dev/docs/libnm/latest/NMSettingConnection.html#
|
|
# NMSettingConnectionDnsOverTls
|
|
DNS_OVER_TLS_STRINGS = {
|
|
'default': gettext_lazy('default'),
|
|
'no': gettext_lazy('no'),
|
|
'opportunistic': gettext_lazy('opportunistic'),
|
|
'yes': gettext_lazy('yes'),
|
|
}
|
|
|
|
|
|
class NetworksAppView(AppView):
|
|
"""Show networks app main page."""
|
|
|
|
app_id = 'networks'
|
|
template_name = 'networks_configuration.html'
|
|
|
|
def get_context_data(self, *args, **kwargs):
|
|
"""Add additional context data for template."""
|
|
connections = network.get_connection_list()
|
|
|
|
network_topology_type = networks.get_network_topology_type()
|
|
internet_connection_type = networks.get_internet_connection_type()
|
|
|
|
context = super().get_context_data(*args, **kwargs)
|
|
context['connections'] = connections
|
|
context['network_topology'] = network_topology_type
|
|
context['internet_connectivity_type'] = internet_connection_type
|
|
return context
|
|
|
|
|
|
def show(request, uuid):
|
|
"""Serve connection information."""
|
|
try:
|
|
connection = network.get_connection(uuid)
|
|
except network.ConnectionNotFound:
|
|
messages.error(request,
|
|
_('Cannot show connection: '
|
|
'Connection not found.'))
|
|
return redirect(reverse_lazy('networks:index'))
|
|
|
|
# Connection status
|
|
connection_status = network.get_status_from_connection(connection)
|
|
connection_status['zone_string'] = dict(network.ZONES).get(
|
|
connection_status['zone'], connection_status['zone'])
|
|
connection_status['dns_over_tls_string'] = DNS_OVER_TLS_STRINGS.get(
|
|
connection_status['dns_over_tls'], connection_status['dns_over_tls'])
|
|
connection_status['ipv4']['method_string'] = CONNECTION_METHOD_STRINGS.get(
|
|
connection_status['ipv4']['method'],
|
|
connection_status['ipv4']['method'])
|
|
connection_status['ipv6']['method_string'] = CONNECTION_METHOD_STRINGS.get(
|
|
connection_status['ipv6']['method'],
|
|
connection_status['ipv6']['method'])
|
|
|
|
# Active connection status
|
|
try:
|
|
active_connection = network.get_active_connection(uuid)
|
|
active_connection_status = \
|
|
network.get_status_from_active_connection(active_connection)
|
|
except network.ConnectionNotFound:
|
|
active_connection_status = {}
|
|
active_connection = None
|
|
|
|
# Device status
|
|
device = None
|
|
if active_connection and active_connection.get_devices():
|
|
device = active_connection.get_devices()[0]
|
|
else:
|
|
interface_name = connection_status['interface_name']
|
|
if interface_name:
|
|
device = network.get_device_by_interface_name(interface_name)
|
|
|
|
device_status = network.get_status_from_device(device)
|
|
device_status['state_string'] = DEVICE_STATE_STRINGS.get(
|
|
device_status['state'], device_status['state'])
|
|
device_status['state_reason_string'] = DEVICE_STATE_REASON_STRINGS.get(
|
|
device_status['state_reason'], device_status['state_reason'])
|
|
device_status['type_string'] = DEVICE_TYPE_STRINGS.get(
|
|
device_status['type'], device_status['type'])
|
|
|
|
# Access point status
|
|
access_point_status = None
|
|
if connection_status['type'] == '802-11-wireless':
|
|
access_point_status = network.get_status_from_wifi_access_point(
|
|
device, connection_status['wireless']['ssid'])
|
|
connection_status['wireless'][
|
|
'mode_string'] = WIRELESS_MODE_STRINGS.get(
|
|
connection_status['wireless']['mode'],
|
|
connection_status['wireless']['mode'])
|
|
|
|
return TemplateResponse(
|
|
request, 'connection_show.html', {
|
|
'title': _('Connection Information'),
|
|
'connection': connection_status,
|
|
'active_connection': active_connection_status,
|
|
'device': device_status,
|
|
'access_point': access_point_status,
|
|
'is_resolved_installed': names.is_resolved_installed()
|
|
})
|
|
|
|
|
|
def edit(request, uuid):
|
|
"""Serve connection editing form."""
|
|
try:
|
|
connection = network.get_connection(uuid)
|
|
except network.ConnectionNotFound:
|
|
messages.error(request,
|
|
_('Cannot edit connection: '
|
|
'Connection not found.'))
|
|
return redirect(reverse_lazy('networks:index'))
|
|
|
|
if connection.get_connection_type() not in network.CONNECTION_TYPE_NAMES:
|
|
messages.error(request,
|
|
_('This type of connection is not yet understood.'))
|
|
return redirect(reverse_lazy('networks:index'))
|
|
|
|
form = None
|
|
form_data = {'name': connection.get_id()}
|
|
|
|
if request.method == 'POST':
|
|
if connection.get_connection_type() == 'generic':
|
|
form = GenericForm(request.POST)
|
|
elif connection.get_connection_type() == '802-11-wireless':
|
|
form = WifiForm(request.POST)
|
|
elif connection.get_connection_type() == '802-3-ethernet':
|
|
form = EthernetForm(request.POST)
|
|
elif connection.get_connection_type() == 'pppoe':
|
|
form = PPPoEForm(request.POST)
|
|
|
|
if form.is_valid():
|
|
network.edit_connection(connection, form.get_settings())
|
|
|
|
return redirect(reverse_lazy('networks:index'))
|
|
else:
|
|
return TemplateResponse(request, 'connections_edit.html', {
|
|
'title': _('Edit Connection'),
|
|
'form': form
|
|
})
|
|
else:
|
|
settings_connection = connection.get_setting_connection()
|
|
form_data['interface'] = connection.get_interface_name()
|
|
try:
|
|
form_data['zone'] = settings_connection.get_zone()
|
|
except KeyError:
|
|
form_data['zone'] = 'external'
|
|
|
|
if settings_connection.get_connection_type() != 'pppoe':
|
|
form_data['dns_over_tls'] = \
|
|
settings_connection.get_dns_over_tls().value_nick
|
|
|
|
settings_ipv4 = connection.get_setting_ip4_config()
|
|
form_data['ipv4_method'] = settings_ipv4.get_method()
|
|
if settings_ipv4.get_num_addresses():
|
|
address = settings_ipv4.get_address(0)
|
|
form_data['ipv4_address'] = address.get_address()
|
|
prefix = address.get_prefix()
|
|
netmask = network.nm.utils_ip4_prefix_to_netmask(prefix)
|
|
form_data['ipv4_netmask'] = network.ipv4_int_to_string(netmask)
|
|
|
|
gateway = settings_ipv4.get_gateway()
|
|
if gateway:
|
|
form_data['ipv4_gateway'] = gateway
|
|
|
|
number_of_dns = settings_ipv4.get_num_dns()
|
|
if number_of_dns:
|
|
form_data['ipv4_dns'] = settings_ipv4.get_dns(0)
|
|
|
|
if number_of_dns > 1:
|
|
form_data['ipv4_second_dns'] = settings_ipv4.get_dns(1)
|
|
|
|
settings_ipv6 = connection.get_setting_ip6_config()
|
|
form_data['ipv6_method'] = settings_ipv6.get_method()
|
|
if settings_ipv6.get_num_addresses():
|
|
address = settings_ipv6.get_address(0)
|
|
form_data['ipv6_address'] = address.get_address()
|
|
form_data['ipv6_prefix'] = address.get_prefix()
|
|
|
|
gateway = settings_ipv6.get_gateway()
|
|
if gateway:
|
|
form_data['ipv6_gateway'] = gateway
|
|
|
|
number_of_dns = settings_ipv6.get_num_dns()
|
|
if number_of_dns:
|
|
form_data['ipv6_dns'] = settings_ipv6.get_dns(0)
|
|
|
|
if number_of_dns > 1:
|
|
form_data['ipv6_second_dns'] = settings_ipv6.get_dns(1)
|
|
|
|
if settings_connection.get_connection_type() == 'generic':
|
|
form = GenericForm(form_data)
|
|
elif settings_connection.get_connection_type() == '802-11-wireless':
|
|
settings_wireless = connection.get_setting_wireless()
|
|
form_data['ssid'] = settings_wireless.get_ssid().get_data().decode(
|
|
)
|
|
form_data['mode'] = settings_wireless.get_mode()
|
|
form_data['band'] = settings_wireless.get_band() or 'auto'
|
|
form_data['channel'] = settings_wireless.get_channel()
|
|
form_data['bssid'] = settings_wireless.get_bssid()
|
|
try:
|
|
wifi_sec = connection.get_setting_wireless_security()
|
|
if wifi_sec:
|
|
if wifi_sec.get_key_mgmt() == 'wpa-psk':
|
|
form_data['auth_mode'] = 'wpa'
|
|
secrets = connection.get_secrets(
|
|
'802-11-wireless-security')
|
|
psk = secrets['802-11-wireless-security']['psk']
|
|
form_data['passphrase'] = psk
|
|
else:
|
|
form_data['auth_mode'] = 'open'
|
|
except KeyError:
|
|
form_data['auth_mode'] = 'open'
|
|
|
|
form = WifiForm(form_data)
|
|
elif settings_connection.get_connection_type() == '802-3-ethernet':
|
|
form = EthernetForm(form_data)
|
|
elif settings_connection.get_connection_type() == 'pppoe':
|
|
settings_pppoe = connection.get_setting_pppoe()
|
|
form_data['username'] = settings_pppoe.get_username()
|
|
secrets = connection.get_secrets('pppoe')
|
|
form_data['password'] = secrets['pppoe']['password']
|
|
form = PPPoEForm(form_data)
|
|
|
|
return TemplateResponse(request, 'connections_edit.html', {
|
|
'title': _('Edit Connection'),
|
|
'form': form
|
|
})
|
|
|
|
|
|
@require_POST
|
|
def activate(request, uuid):
|
|
"""Activate the connection."""
|
|
try:
|
|
connection = network.activate_connection(uuid)
|
|
name = connection.get_id()
|
|
messages.success(request,
|
|
_('Activated connection {name}.').format(name=name))
|
|
except network.ConnectionNotFound:
|
|
messages.error(
|
|
request,
|
|
_('Failed to activate connection: '
|
|
'Connection not found.'))
|
|
except network.DeviceNotFound as exception:
|
|
name = exception.args[0].get_id()
|
|
messages.error(
|
|
request,
|
|
_('Failed to activate connection {name}: '
|
|
'No suitable device is available.').format(name=name))
|
|
|
|
return redirect(reverse_lazy('networks:index'))
|
|
|
|
|
|
@require_POST
|
|
def deactivate(request, uuid):
|
|
"""Deactivate the connection."""
|
|
try:
|
|
active_connection = network.deactivate_connection(uuid)
|
|
name = active_connection.get_id()
|
|
messages.success(request,
|
|
_('Deactivated connection {name}.').format(name=name))
|
|
except network.ConnectionNotFound:
|
|
messages.error(
|
|
request,
|
|
_('Failed to de-activate connection: '
|
|
'Connection not found.'))
|
|
|
|
return redirect(reverse_lazy('networks:index'))
|
|
|
|
|
|
def scan(request):
|
|
"""Show a list of nearby visible Wi-Fi access points."""
|
|
device_access_points = network.wifi_scan()
|
|
scanning = any(
|
|
(device['scan_requested'] for device in device_access_points))
|
|
# Refresh page in 10s if scanning, 60s otherwise
|
|
refresh_page_sec = 10 if scanning else 60
|
|
return TemplateResponse(
|
|
request, 'wifi_scan.html', {
|
|
'title': _('Nearby Wi-Fi Networks'),
|
|
'device_access_points': device_access_points,
|
|
'refresh_page_sec': refresh_page_sec
|
|
})
|
|
|
|
|
|
def add(request):
|
|
"""Serve the connection type selection form."""
|
|
form = None
|
|
|
|
if request.method == 'POST':
|
|
form = ConnectionTypeSelectForm(request.POST)
|
|
if form.is_valid():
|
|
connection_type = form.cleaned_data['connection_type']
|
|
if connection_type == 'generic':
|
|
return redirect(reverse_lazy('networks:add_generic'))
|
|
elif connection_type == '802-3-ethernet':
|
|
return redirect(reverse_lazy('networks:add_ethernet'))
|
|
elif connection_type == '802-11-wireless':
|
|
return redirect(reverse_lazy('networks:add_wifi'))
|
|
elif connection_type == 'pppoe':
|
|
return redirect(reverse_lazy('networks:add_pppoe'))
|
|
else:
|
|
form = ConnectionTypeSelectForm()
|
|
return TemplateResponse(request, 'connections_type_select.html', {
|
|
'title': _('Add Connection'),
|
|
'form': form
|
|
})
|
|
|
|
|
|
def add_generic(request):
|
|
"""Serve generic connection create form."""
|
|
form = None
|
|
|
|
if request.method == 'POST':
|
|
form = GenericForm(request.POST)
|
|
if form.is_valid():
|
|
network.add_connection(form.get_settings())
|
|
return redirect(reverse_lazy('networks:index'))
|
|
else:
|
|
form = GenericForm()
|
|
|
|
return TemplateResponse(request, 'connections_create.html', {
|
|
'title': _('Adding New Generic Connection'),
|
|
'form': form
|
|
})
|
|
|
|
|
|
def add_ethernet(request):
|
|
"""Serve ethernet connection create form."""
|
|
form = None
|
|
|
|
if request.method == 'POST':
|
|
form = EthernetForm(request.POST)
|
|
if form.is_valid():
|
|
network.add_connection(form.get_settings())
|
|
return redirect(reverse_lazy('networks:index'))
|
|
else:
|
|
form = EthernetForm()
|
|
|
|
return TemplateResponse(request, 'connections_create.html', {
|
|
'title': _('Adding New Ethernet Connection'),
|
|
'form': form
|
|
})
|
|
|
|
|
|
def add_pppoe(request):
|
|
"""Serve pppoe connection create form."""
|
|
form = None
|
|
|
|
if request.method == 'POST':
|
|
form = PPPoEForm(request.POST)
|
|
if form.is_valid():
|
|
network.add_connection(form.get_settings())
|
|
return redirect(reverse_lazy('networks:index'))
|
|
else:
|
|
form = PPPoEForm()
|
|
|
|
return TemplateResponse(request, 'connections_create.html', {
|
|
'title': _('Adding New PPPoE Connection'),
|
|
'form': form
|
|
})
|
|
|
|
|
|
def add_wifi(request, ssid=None, interface_name=None):
|
|
"""Serve wifi connection create form."""
|
|
form = None
|
|
form_data = None
|
|
|
|
if ssid:
|
|
device = network.get_device_by_interface_name(interface_name)
|
|
form_data = {
|
|
'name': ssid,
|
|
'interface': interface_name if device else None,
|
|
'zone': 'external',
|
|
'ssid': ssid,
|
|
'mode': 'infrastructure',
|
|
'band': 'auto',
|
|
'auth_mode': 'wpa',
|
|
'ipv4_method': 'auto',
|
|
'ipv6_method': 'auto',
|
|
'dns_over_tls': 'default',
|
|
}
|
|
|
|
if request.method == 'POST':
|
|
form = WifiForm(request.POST)
|
|
if form.is_valid():
|
|
network.add_connection(form.get_settings())
|
|
return redirect(reverse_lazy('networks:index'))
|
|
else:
|
|
if form_data:
|
|
form = WifiForm(form_data)
|
|
else:
|
|
form = WifiForm()
|
|
|
|
return TemplateResponse(request, 'connections_create.html', {
|
|
'title': _('Adding New Wi-Fi Connection'),
|
|
'form': form
|
|
})
|
|
|
|
|
|
def delete(request, uuid):
|
|
"""Handle deleting connections, showing a confirmation dialog first.
|
|
|
|
On GET, display a confirmation page.
|
|
On POST, delete the connection.
|
|
"""
|
|
if request.method == 'POST':
|
|
try:
|
|
name = network.delete_connection(uuid)
|
|
messages.success(request,
|
|
_('Connection {name} deleted.').format(name=name))
|
|
except network.ConnectionNotFound:
|
|
messages.error(
|
|
request,
|
|
_('Failed to delete connection: '
|
|
'Connection not found.'))
|
|
|
|
return redirect(reverse_lazy('networks:index'))
|
|
|
|
try:
|
|
connection = network.get_connection(uuid)
|
|
name = connection.get_id()
|
|
except network.ConnectionNotFound:
|
|
messages.error(
|
|
request, _('Failed to delete connection: '
|
|
'Connection not found.'))
|
|
return redirect(reverse_lazy('networks:index'))
|
|
|
|
return TemplateResponse(request, 'connections_delete.html', {
|
|
'title': _('Delete Connection'),
|
|
'name': name
|
|
})
|
|
|
|
|
|
class NetworkTopologyView(FormView):
|
|
"""View for local network topology form."""
|
|
template_name = 'network_topology_update.html'
|
|
form_class = NetworkTopologyForm
|
|
success_url = reverse_lazy('networks:index')
|
|
|
|
def get_initial(self):
|
|
"""Get initial form data."""
|
|
return {'network_topology': networks.get_network_topology_type()}
|
|
|
|
def form_valid(self, form):
|
|
"""Save value to DB."""
|
|
network_topology = form.cleaned_data['network_topology']
|
|
logger.info('Updating network topology type with value %s' %
|
|
network_topology)
|
|
networks.set_network_topology_type(network_topology)
|
|
if network_topology == 'to_router':
|
|
self.success_url = reverse_lazy('networks:router-configuration')
|
|
|
|
return super().form_valid(form)
|
|
|
|
|
|
class RouterConfigurationView(FormView):
|
|
"""View for router configuration form."""
|
|
template_name = 'router_configuration_update.html'
|
|
form_class = RouterConfigurationForm
|
|
success_url = reverse_lazy('networks:index')
|
|
|
|
def get_initial(self):
|
|
"""Return initial data for the form."""
|
|
return {'router_config': networks.get_router_configuration_type()}
|
|
|
|
def form_valid(self, form):
|
|
"""Save value to DB and redirect."""
|
|
type_ = form.cleaned_data['router_config']
|
|
logger.info('Updating router configuration: %s', type_)
|
|
networks.set_router_configuration_type(type_)
|
|
return super().form_valid(form)
|
|
|
|
|
|
class InternetConnectionTypeView(FormView):
|
|
"""View for Internet connection type form."""
|
|
template_name = 'internet_connectivity_type.html'
|
|
form_class = InternetConnectionTypeForm
|
|
success_url = reverse_lazy('networks:index')
|
|
|
|
def get_initial(self):
|
|
"""Return initial data for the form."""
|
|
return {
|
|
'internet_connection_type':
|
|
networks.get_internet_connection_type()
|
|
}
|
|
|
|
def form_valid(self, form):
|
|
"""Save value to DB and redirect."""
|
|
type_ = form.cleaned_data['internet_connection_type']
|
|
logger.info('Updating internet connectivity type: %s', type_)
|
|
networks.set_internet_connection_type(type_)
|
|
return super().form_valid(form)
|