class Migration(migrations.Migration): dependencies = [ ('dataframe_store', '0002_parent'), ] operations = [ migrations.AddField( model_name='dbdataframe', name='parent', field=mptt.fields.TreeForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=swapper.get_model_name('dataframe_store', 'DbDataFrame')), ), migrations.AddField( model_name='dbdataframe', name='labels', field=models.ManyToManyField(blank=True, to=swapper.get_model_name( 'dataframe_store', 'Label')), ), migrations.AlterIndexTogether( name='dbdataframe', index_together={('shape_x', 'shape_y')}, ), ]
class Migration(migrations.Migration): initial = True dependencies = [swapper.dependency('openwisp_users', 'Organization')] operations = [ migrations.CreateModel( name='Config', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ('name', models.CharField(max_length=16)), ( 'organization', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={'abstract': False}, ), migrations.CreateModel( name='Template', fields=[ ( 'id', models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name='ID', ), ), ('name', models.CharField(max_length=16)), ( 'organization', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=swapper.get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ], options={'abstract': False}, ), ]
class AbstractResidentialInformation(Model): """ This model holds residential information about a person """ person = models.OneToOneField( to=swapper.get_model_name('kernel', 'Person'), on_delete=models.CASCADE, ) residence = models.ForeignKey( to=swapper.get_model_name('kernel', 'Residence'), on_delete=models.CASCADE, ) room_number = models.CharField(max_length=15, ) class Meta: """ Meta class for AbstractResidentialInformation """ abstract = True def __str__(self): """ Return the string representation of the model :return: the string representation of the model """ person = self.person room_number = self.room_number residence = self.residence return f'{person} - {room_number}, {residence}'
def register_menu_groups(self): register_menu_group( position=110, config={ 'label': 'Network Topology', 'items': { 1: { 'label': _('Topologies'), 'model': get_model_name('topology', 'Topology'), 'name': 'changelist', 'icon': 'ow-topology', }, 2: { 'label': _('Nodes'), 'model': get_model_name('topology', 'Node'), 'name': 'changelist', 'icon': 'ow-node', }, 3: { 'label': _('Links'), 'model': get_model_name('topology', 'Link'), 'name': 'changelist', 'icon': 'ow-link', }, }, 'icon': 'ow-network-topology', }, )
class DeviceData(AbstractDeviceData, BaseDevice): checks = GenericRelation(get_model_name('check', 'Check')) metrics = GenericRelation(get_model_name('monitoring', 'Metric')) class Meta: proxy = True swappable = swappable_setting('device_monitoring', 'DeviceData')
class BaseDeviceLocation(ValidateOrgMixin, AbstractObjectLocation): # remove generic foreign key attributes # (we use a direct foreign key to Device) content_type = None object_id = None # reuse the same generic attribute name used in django-loci content_object = models.OneToOneField( get_model_name('config', 'Device'), models.CASCADE ) # override parent foreign key targets location = models.ForeignKey( get_model_name('geo', 'Location'), models.PROTECT, blank=True, null=True ) floorplan = models.ForeignKey( get_model_name('geo', 'FloorPlan'), models.PROTECT, blank=True, null=True ) class Meta(AbstractObjectLocation.Meta): abstract = True # remove AbstractObjectLocation.Meta.unique_together unique_together = None def clean(self): self._validate_org_relation('location', field_error='location') self._validate_org_relation('floorplan', field_error='floorplan') super().clean() @property def device(self): return self.content_object @property def organization_id(self): return self.device.organization_id
def update_admins_permissions(apps, schema_editor): org_model = swapper.get_model_name('openwisp_users', 'organization') model_app_label = swapper.split(org_model)[0] group = apps.get_model(model_app_label, 'group') email_model = swapper.get_model_name('account', 'EmailAddress') email_app_label = swapper.split(email_model)[0] try: admin = group.objects.get(name='Administrator') permissions = [ Permission.objects.get( content_type__app_label=email_app_label, codename='view_emailaddress' ).pk, Permission.objects.get( content_type__app_label=email_app_label, codename='delete_emailaddress' ).pk, Permission.objects.get( content_type__app_label=email_app_label, codename='change_emailaddress' ).pk, Permission.objects.get( content_type__app_label=model_app_label, codename='delete_user' ).pk, ] admin.permissions.add(*permissions) except ObjectDoesNotExist: pass
class AbstractSubnet(TimeStampedEditableModel): """ An abstract base class which contains all the subnet details """ name = models.CharField(verbose_name=_('name') max_length=64) details = models.CharField(verbose_name=_('details'), max_length=64) subnet = models.ForeignKey(swapper.get_model_name('django_ipam','Subnet'), null=True) section = models.ForeignKey(swapper.get_model_name('django_ipam', 'Section')) description = models.TextField(verbose_name=_('description')) gateway = models.GenericIPAddressField() @property def subnet_usage(self): total_addresses = IPNetwork(self.details).size ip_model = swapper.load_model('django_ipam', 'IPAddress') used = ip_model.objects.filter(subnet=self, ip_status='used').count() free = total_addresses - used return "free: {0}, used: {1}, total: {2}".format(free, used, total_addresses) class Meta: abstract = True
class PostalCode(Place, SlugModel): code = models.CharField(max_length=20) location = models.PointField() country = models.ForeignKey(swapper.get_model_name('cities', 'Country'), related_name='postal_codes') # Region names for each admin level, region may not exist in DB region_name = models.CharField(max_length=100, db_index=True) subregion_name = models.CharField(max_length=100, db_index=True) district_name = models.CharField(max_length=100, db_index=True) region = models.ForeignKey(Region, blank=True, null=True, related_name='postal_codes') subregion = models.ForeignKey(Subregion, blank=True, null=True, related_name='postal_codes') city = models.ForeignKey(swapper.get_model_name('cities', 'City'), blank=True, null=True, related_name='postal_codes') district = models.ForeignKey(District, blank=True, null=True, related_name='postal_codes') objects = models.GeoManager() @property def parent(self): return self.country @property def name_full(self): """Get full name including hierarchy""" return force_text(', '.join(reversed(self.names))) @property def names(self): """Get a hierarchy of non-null names, root first""" return [ e for e in [ force_text(self.country), force_text(self.region_name), force_text(self.subregion_name), force_text(self.district_name), force_text(self.name), ] if e ] def __str__(self): return force_text(self.code) def slugify(self): return slugify_func(self, unicode(self.id))
def add_default_menu_items(self): menu_setting = 'OPENWISP_DEFAULT_ADMIN_MENU_ITEMS' items = [ {'model': get_model_name('config', 'Device')}, {'model': get_model_name('config', 'Template')}, {'model': get_model_name('config', 'Vpn')}, ] if not hasattr(settings, menu_setting): setattr(settings, menu_setting, items) else: current_menu = getattr(settings, menu_setting) current_menu += items
class FeatureUsage(TimeStampedModel): feature = models.ForeignKey(swapper.get_model_name('flexible_plans', 'Feature'), on_delete=models.DO_NOTHING) subscription = models.ForeignKey(swapper.get_model_name( 'flexible_plans', 'Subscription'), on_delete=models.DO_NOTHING) consumed_units = models.DecimalField(max_digits=10, decimal_places=2) def __str__(self): return "{} {} - {}".format(self.feature, self.subscription, self.consumed_units)
def ready(self, *args, **kwargs): super().ready(*args, **kwargs) patch_ipaddress_lib() items = [ { 'model': get_model_name('openwisp_ipam', 'Subnet') }, { 'model': get_model_name('openwisp_ipam', 'IpAddress') }, ] register_menu_items(items, name_menu='OPENWISP_DEFAULT_ADMIN_MENU_ITEMS')
def regiser_menu_groups(self): items = { 1: { 'label': _('Accounting Sessions'), 'model': get_model_name(self.label, 'RadiusAccounting'), 'name': 'changelist', 'icon': 'ow-radius-accounting', }, 2: { 'label': _('Groups'), 'model': get_model_name(self.label, 'RadiusGroup'), 'name': 'changelist', 'icon': 'ow-radius-group', }, 3: { 'label': _('NAS'), 'model': get_model_name(self.label, 'Nas'), 'name': 'changelist', 'icon': 'ow-radius-nas', }, 4: { 'label': _('Checks'), 'model': get_model_name(self.label, 'RadiusCheck'), 'name': 'changelist', 'icon': 'ow-radius-checks', }, 5: { 'label': _('Replies'), 'model': get_model_name(self.label, 'RadiusReply'), 'name': 'changelist', 'icon': 'ow-radius-replies', }, 6: { 'label': _('Batch user Creation'), 'model': get_model_name(self.label, 'RadiusBatch'), 'name': 'changelist', 'icon': 'ow-batch-creation', }, 7: { 'label': _('Post Auth Log'), 'model': get_model_name(self.label, 'RadiusPostAuth'), 'name': 'changelist', 'icon': 'ow-radius-post-log', }, } if getattr(app_settings, 'DEBUG', False): items[8] = { 'label': _('Radius Token'), 'model': get_model_name(self.label, 'RadiusToken'), 'name': 'changelist', 'icon': 'ow-radius-token', } register_menu_group( position=70, config={ 'label': _('RADIUS'), 'items': items, 'icon': 'ow-radius' }, )
class AbstractWifiSession(TimeStampedEditableModel): created = None device = models.ForeignKey( swapper.get_model_name('config', 'Device'), on_delete=models.CASCADE, ) wifi_client = models.ForeignKey( swapper.get_model_name('device_monitoring', 'WifiClient'), on_delete=models.CASCADE, ) ssid = models.CharField(max_length=32, blank=True, null=True, verbose_name=_('SSID')) interface_name = models.CharField(max_length=15, ) start_time = models.DateTimeField( verbose_name=_('start time'), db_index=True, auto_now=True, ) stop_time = models.DateTimeField( verbose_name=_('stop time'), db_index=True, null=True, blank=True, ) class Meta: abstract = True verbose_name = _('WiFi Session') ordering = ('-start_time', ) def __str__(self): return self.mac_address @property def mac_address(self): return self.wifi_client.mac_address @property def vendor(self): return self.wifi_client.vendor @classmethod def offline_device_close_session(cls, instance, *args, **kwargs): if kwargs['status'] == 'critical': tasks.offline_device_close_session.delay( device_id=instance.device_id)
class AbstractOrganizationConfigSettings(UUIDModel): organization = models.OneToOneField( swapper.get_model_name('openwisp_users', 'Organization'), verbose_name=_('organization'), related_name='config_settings', on_delete=models.CASCADE, ) registration_enabled = models.BooleanField( _('auto-registration enabled'), default=True, help_text=_('Whether automatic registration of devices is enabled or not'), ) shared_secret = KeyField( max_length=32, unique=True, db_index=True, verbose_name=_('shared secret'), help_text=_('used for automatic registration of devices'), ) class Meta: verbose_name = _('Configuration management settings') verbose_name_plural = verbose_name abstract = True def __str__(self): return self.organization.name
class AbstractIpAddress(TimeStampedEditableModel): subnet = models.ForeignKey(get_model_name('django_ipam', 'Subnet'), on_delete=models.CASCADE) ip_address = models.GenericIPAddressField() description = models.CharField(max_length=100, blank=True) class Meta: abstract = True def __str__(self): return self.ip_address def clean(self): if not self.ip_address or not self.subnet_id: return if ip_address(self.ip_address) not in self.subnet.subnet: raise ValidationError( {'ip_address': _('IP address does not belong to the subnet')}) addresses = load_model('django_ipam', 'IpAddress').objects.all().values() for ip in addresses: if self.id == ip['id']: continue if ip_address(self.ip_address) == ip_address(ip['ip_address']): raise ValidationError( {'ip_address': _('IP address already used.')})
class Migration(migrations.Migration): dependencies = [ ('openwisp_radius', '0013_remove_null_uuid_field'), ] operations = [ migrations.RunPython(delete_old_radius_token, reverse_code=migrations.RunPython.noop), migrations.AddField( model_name='radiustoken', name='can_auth', field=models.BooleanField( default=False, help_text=('Enable the radius token to be used ' 'for freeradius authorization request'), ), ), migrations.AddField( model_name='radiustoken', name='organization', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=get_model_name('openwisp_users', 'Organization'), verbose_name='organization', ), ), ]
class BaseCountry(Place, SlugModel): code = models.CharField(max_length=2, db_index=True, unique=True) code3 = models.CharField(max_length=3, db_index=True, unique=True) population = models.IntegerField() area = models.IntegerField(null=True) currency = models.CharField(max_length=3, null=True) currency_name = models.CharField(max_length=50, blank=True, null=True) currency_symbol = models.CharField(max_length=31, blank=True, null=True) language_codes = models.CharField(max_length=250, null=True) phone = models.CharField(max_length=20) continent = models.ForeignKey(swapper.get_model_name('cities', 'Continent'), null=True, related_name='%(app_label)s_%(class)s_countries') tld = models.CharField(max_length=5, verbose_name='TLD') postal_code_format = models.CharField(max_length=127) postal_code_regex = models.CharField(max_length=255) capital = models.CharField(max_length=100) neighbours = models.ManyToManyField("self") class Meta: abstract = True ordering = ['name'] verbose_name_plural = "countries" @property def parent(self): return None def __str__(self): return force_text(self.name) def clean(self): self.tld = self.tld.lower() def slugify(self): return self.name
class Complaint(Model): """ Describes the details of a complaint registered. """ person = models.ForeignKey( to=swapper.get_model_name("Kernel", "Person"), on_delete=models.CASCADE, ) complaint_type = models.CharField( max_length=10, choices=complaint_types.COMPLAINT_TYPES, default=complaint_types.OTHER, ) status = models.CharField(max_length=10, choices=statuses.COMLAINT_STATUSES, default=statuses.PENDING) description = models.TextField() failed_attempts = models.PositiveIntegerField( default=0, validators=[MaxValueValidator(3)], ) def __str__(self): """ Return the string representation of the model :return: the string representation of the model """ complaint_type = self.get_complaint_type_display() room_no = self.person.residentialinformation.room_number return f"{complaint_type} issue in {room_no}"
class TestApp(UUIDModel): name = models.CharField(max_length=50) organization = models.ForeignKey( get_model_name('openwisp_users', 'Organization'), on_delete=models.CASCADE, ) class Meta: verbose_name = _('Test App') verbose_name_plural = verbose_name def __str__(self): return self.name def save(self, *args, **kwargs): self._check_name_changed() super().save(*args, **kwargs) def _check_name_changed(self): try: obj = self._meta.model.objects.get(id=self.id) except ObjectDoesNotExist: return else: if obj.name != self.name: test_app_name_changed.send(sender=self.__class__, instance=self)
class District(Place, SlugModel): slug_contains_id = True name_std = models.CharField(max_length=200, db_index=True, verbose_name="standard name") code = models.CharField(blank=True, db_index=True, max_length=200, null=True) location = PointField() population = models.IntegerField() city = models.ForeignKey(swapper.get_model_name('cities', 'City'), related_name='districts', on_delete=SET_NULL_OR_CASCADE) class Meta: unique_together = (('city', 'name'), ) @property def parent(self): return self.city def slugify(self): if self.id: return '{}-{}'.format(self.id, unicode_func(self.name)) return None
class Event(Model): """ This model contains information about a facility of a hostel """ hostel = models.ForeignKey( to=swapper.get_model_name("kernel", "Residence"), on_delete=models.CASCADE, ) name = models.CharField(max_length=63, ) description = models.TextField( blank=True, null=True, ) display_picture = models.ImageField( upload_to=UploadTo("bhawan_app", "hostel"), max_length=255, blank=True, null=True, ) timings = models.ManyToManyField(Timing, ) date = models.DateField() def __str__(self): """ Return the string representation of the model :return: the string representation of the model """ name = self.name return f"{name}"
class AbstractCert(BaseX509): """ Abstract Cert model """ ca = models.ForeignKey( swapper.get_model_name('django_x509', 'Ca'), on_delete=models.CASCADE, verbose_name=_('CA'), ) revoked = models.BooleanField(_('revoked'), default=False) revoked_at = models.DateTimeField(_('revoked at'), blank=True, null=True, default=None) def __str__(self): return self.name class Meta: abstract = True verbose_name = _('certificate') verbose_name_plural = _('certificates') unique_together = ('ca', 'serial_number') def revoke(self): """ * flag certificate as revoked * fill in revoked_at DateTimeField """ now = timezone.now() self.revoked = True self.revoked_at = now self.save()
class AlbumUpload(models.Model): zip_file = models.FileField( verbose_name=_('images file (.zip)'), upload_to=TEMP_DIR, help_text=_('Select a .zip file of images to upload into a new Gallery.')) album = models.ForeignKey( swapper.get_model_name('imagestore', 'Album'), on_delete=models.CASCADE, blank=True, null=True, help_text=_('Select an album to add these images to. leave this empty ' 'to create a new album from the supplied title.')) new_album_name = models.CharField( verbose_name=_('New album name'), max_length=255, blank=True, help_text=_('If not empty new album with this name will be created ' 'and images will be upload to this album')) tags = models.CharField(verbose_name=_('tags'), max_length=255, blank=True) class Meta: app_label = 'imagestore' verbose_name = _('Album upload') verbose_name_plural = _('Album uploads') def save(self, *args, **kwargs): super(AlbumUpload, self).save(*args, **kwargs) upload_processor(self) def delete(self, *args, **kwargs): storage, path = self.zip_file.storage, self.zip_file.name super(AlbumUpload, self).delete(*args, **kwargs) storage.delete(path)
class BaseCity(Place, SlugModel): slug_contains_id = True name_std = models.CharField(max_length=200, db_index=True, verbose_name="standard name") country = models.ForeignKey(swapper.get_model_name('cities', 'Country'), related_name='cities') region = models.ForeignKey(Region, null=True, blank=True, related_name='cities') subregion = models.ForeignKey(Subregion, null=True, blank=True, related_name='cities') location = models.PointField() population = models.IntegerField() elevation = models.IntegerField(null=True) kind = models.CharField(max_length=10) # http://www.geonames.org/export/codes.html timezone = models.CharField(max_length=40) class Meta: abstract = True unique_together = (('country', 'region', 'subregion', 'id', 'name'),) verbose_name_plural = "cities" @property def parent(self): return self.region def slugify(self): if self.id: return '{}-{}'.format(self.id, unicode_func(self.name)) return None
def test_check_inline_formset(self): d = self._create_device(organization=self._create_org()) check_inline_formset = generic_inlineformset_factory( model=Check, form=CheckInline.form, formset=CheckInlineFormSet) # model_name changes if swapped model_name = get_model_name('check', 'Check').lower().replace('.', '-') ct = f'{model_name}-content_type-object_id' data = { f'{ct}-TOTAL_FORMS': '1', f'{ct}-INITIAL_FORMS': '0', f'{ct}-MAX_NUM_FORMS': '0', f'{ct}-0-name': 'Ping Check', f'{ct}-0-check': CHECK_CLASSES[0][0], f'{ct}-0-params': '{}', f'{ct}-0-is_active': True, f'{ct}-0-created': now(), f'{ct}-0-modified': now(), } formset = check_inline_formset(data) formset.instance = d self.assertTrue(formset.is_valid()) self.assertEqual(formset.errors, [{}]) self.assertEqual(formset.non_form_errors(), []) form = formset.forms[0] form.cleaned_data = data form.save(commit=True) self.assertEqual(Check.objects.count(), 1) c = Check.objects.first() self.assertEqual(c.name, 'Ping Check') self.assertEqual(c.content_object, d)
class AbstractAdministrativeAreaLevel1Model(models.Model): """Abstract administrative area level 1 model (example: State or Region).""" name = models.CharField(_("Name"), max_length=150) code = models.CharField(_("Code"), max_length=5, blank=True, default="") country = models.ForeignKey( to=swapper.get_model_name("django_address", "Country"), on_delete=models.PROTECT, verbose_name=_("Country"), ) objects = GetOrNoneManager() class Meta: abstract = True ordering = ("country", "name") unique_together = (("name", "country"),) def __str__(self): country = "{country}".format(country=self.country) name = "{name}".format(name=self.name or self.code) if country: return "{name}, {country}".format(name=name, country=country) return name or country def to_dict(self): return model_to_dict(self, fields=[field.name for field in self._meta.fields])
class PlanFeature(models.Model): plan = models.ForeignKey('Plan', on_delete=models.CASCADE) feature = models.ForeignKey(swapper.get_model_name('flexible_plans', 'Feature'), blank=True, null=True, on_delete=models.SET_NULL)
class Place(models.Model): name = models.CharField(max_length=200, db_index=True, verbose_name="ascii name") alt_names = models.ManyToManyField(swapper.get_model_name('cities', 'AlternativeName')) perimeter = models.MultiPolygonField(null=True, blank=True) objects = GeoManager() class Meta: abstract = True @property def hierarchy(self): """Get hierarchy, root first""" lst = self.parent.hierarchy if self.parent else [] lst.append(self) return lst def get_absolute_url(self): return "/".join([place.slug for place in self.hierarchy]) def __str__(self): return force_text(self.name) def save(self, *args, **kwargs): if hasattr(self, 'clean'): self.clean() super(Place, self).save(*args, **kwargs)
class Visitor(Model): """ This model contains information about the visitor of a hostel room """ person = models.ForeignKey( to=swapper.get_model_name('kernel', 'Person'), on_delete=models.CASCADE, ) booking = models.ForeignKey( RoomBooking, on_delete=models.CASCADE, related_name='visitor', ) relation = models.CharField(max_length=50, ) photo_identification = models.FileField( upload_to=UploadTo('bhawan_app', 'visitor_id')) def __str__(self): """ Return the string representation of the model :return: the string representation of the model """ ResidentialInformation = swapper.load_model( 'kernel', 'ResidentialInformation', ) full_name = self.person.full_name relation = self.relation booked_by = self.booking.person booked_by_name = booked_by.full_name booked_by_room_no = booked_by.residentialinformation.room_number return (f'{full_name} - {relation} of {booked_by_name} | ' f'{booked_by_room_no}')
def get_model(apps, name): model_tuple = swapper.split(swapper.get_model_name('cities', name)) return apps.get_model(*model_tuple)
#!/usr/bin/env python # vim:fileencoding=utf-8 from __future__ import unicode_literals import django from django.db import models import swapper if django.VERSION[:2] < (1, 5): if swapper.is_swapped('imagestore', 'Album'): app_name, model_name = swapper.get_model_name('imagestore', 'Album').split('.') Album = models.get_model(app_name, model_name) else: from .album import Album if swapper.is_swapped('imagestore', 'Image'): app_name, model_name = swapper.get_model_name('imagestore', 'Image').split('.') Image = models.get_model(app_name, model_name) else: from .image import Image else: from .album import Album from .image import Image from .upload import AlbumUpload
def test_swap_setting(self): self.assertTrue(swapper.is_swapped("default_app", "Type")) self.assertEqual( swapper.get_model_name("default_app", "Type"), "alt_app.Type" )
def get_star_ratings_rating_model_name(): return swapper.get_model_name('star_ratings', 'Rating')