Skip to content

Commit

Permalink
Merge pull request #120 from luftdaten-at/111-geräte-kann-usern-zugeo…
Browse files Browse the repository at this point in the history
…rdnet-werden

111 geräte kann usern zugeordnet werden
  • Loading branch information
n11ik authored Jan 22, 2025
2 parents 9a59914 + 6df4c4c commit 1f2bc0c
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 8 deletions.
1 change: 1 addition & 0 deletions app/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ def post(self, request, *args, **kwargs):
time_measured=station_data['time'],
time_received=time_received,
room = station.current_room,
user = station.current_user,
)
measurement.save()

Expand Down
56 changes: 55 additions & 1 deletion app/campaign/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,58 @@ def save(self, commit=True):
# Save the room
room.save()

return room
return room


class UserDeviceForm(forms.ModelForm):
current_devices = (forms.ModelMultipleChoiceField(label='',
queryset=Device.objects.none(),
widget=FilteredSelectMultiple(
verbose_name='Devices',
is_stacked=False,
),
required=False))

class Meta:
model = Room
fields = ['current_devices']

class Media:
css = {
'all': ('/static/admin/css/widgets.css', '/static/css/adminoverrides.css', ),
} # custom css

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# Get the user from the passed arguments (initial data)
self.user = kwargs.get('initial', {}).get('user', None)
self.campaign = kwargs.get('initial', {}).get('campaign', None)

# query set should be a list of all devices in the same organisation as the room is
self.fields['current_devices'].queryset = self.campaign.organization.current_devices.all()
self.initial['current_devices'] = self.user.current_devices.all()

# Initialize form helper
self.helper = FormHelper(self)
self.helper.add_input(Submit('submit', 'Save'))

def save(self, commit=True):
# Save the room instance
user = super().save(commit=commit)

# Get the selected devices
selected_devices = self.cleaned_data['current_devices']

# Update the ForeignKey for the devices
if commit:
# Unassign the devices previously linked to the room
Device.objects.filter(current_user=user).update(current_user=None)

# Assign the selected devices to the current room
selected_devices.update(current_user=user)

# Save the room
user.save()

return user
1 change: 1 addition & 0 deletions app/campaign/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
path('<str:pk>/delete/', CampaignsDeleteView.as_view(), name='campaigns-delete'),
path('<str:pk>/add-user/', CampaignAddUserView.as_view(), name='campaign-add-user'),
path('<str:pk>/participants/<int:user>/', ParticipantDetailView.as_view(), name='participants-detail'),
path('<str:campaign_pk>/participants/<int:pk>/add-devices', ParticipantsAddDevicesView.as_view(), name='user-add-device'),
path('rooms/<int:pk>/', RoomDetailView.as_view(), name='room-detail'),
path('rooms/<int:pk>/delete/', RoomDeleteView.as_view(), name='room-delete'),
path('rooms/<int:pk>/add-device/', RoomAddDeviceView.as_view(),name='room-add-device'),
Expand Down
27 changes: 26 additions & 1 deletion app/campaign/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


from .models import Campaign, Room
from .forms import CampaignForm, CampaignUserForm, RoomDeviceForm
from .forms import CampaignForm, CampaignUserForm, RoomDeviceForm, UserDeviceForm
from accounts.models import CustomUser
from main.enums import Dimension, SensorModel

Expand Down Expand Up @@ -442,3 +442,28 @@ def dispatch(self, request, *args, **kwargs):

def get_success_url(self):
return reverse_lazy('campaigns-detail', kwargs={'pk': self.campaign.pk})


class ParticipantsAddDevicesView(LoginRequiredMixin, UpdateView):
model = CustomUser
form_class = UserDeviceForm
template_name = 'campaigns/participants/add_device.html'

def get_success_url(self):
return reverse_lazy('campaigns-detail', kwargs={'pk': self.campaign.pk})

def dispatch(self, request, *args, **kwargs):
self.campaign = Campaign.objects.get(pk=kwargs['campaign_pk'])

if self.request.user.is_superuser:
return super().dispatch(request, *args, **kwargs)
if self.request.user != self.campaign.owner:
raise PermissionDenied("You are not allowed to create a Room")

return super().dispatch(request, *args, **kwargs)

def get_initial(self):
initial = super().get_initial()
initial['campaign'] = self.campaign
initial['user'] = self.object
return initial
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 5.1.2 on 2025-01-21 09:28

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('campaign', '0009_remove_organization_owner_remove_organization_users_and_more'),
('devices', '0012_alter_device_current_organization'),
('organizations', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.AddField(
model_name='device',
name='current_user',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='current_devices', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='measurement',
name='user',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='measurements', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='device',
name='current_organization',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='current_devices', to='organizations.organization'),
),
migrations.AlterField(
model_name='device',
name='current_room',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='current_devices', to='campaign.room'),
),
]
7 changes: 5 additions & 2 deletions app/devices/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.utils import timezone
from organizations.models import Organization
from campaign.models import Room
from accounts.models import CustomUser


class Device(models.Model):
Expand All @@ -16,8 +17,9 @@ class Device(models.Model):
last_update = models.DateTimeField(null=True, blank=True)
notes = models.TextField(null=True, blank=True)
api_key = models.CharField(max_length=64, null=True)
current_room = models.ForeignKey(Room, on_delete=models.CASCADE, related_name='current_devices', null=True)
current_organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name='current_devices', null=True)
current_room = models.ForeignKey(Room, related_name='current_devices', null=True, on_delete=models.SET_NULL)
current_organization = models.ForeignKey(Organization, related_name='current_devices', null=True, on_delete=models.SET_NULL)
current_user = models.ForeignKey(CustomUser, null=True, related_name='current_devices', on_delete=models.SET_NULL)

def __str__(self):
return self.id or "Undefined Device" # Added fallback for undefined IDs
Expand Down Expand Up @@ -80,6 +82,7 @@ class Measurement(models.Model):
sensor_model = models.IntegerField()
device = models.ForeignKey(Device, on_delete=models.CASCADE, related_name='measurements')
room = models.ForeignKey(Room, on_delete=models.CASCADE, null=True, related_name='measurements')
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, null=True, related_name='measurements')

def __str__(self):
return f'Measurement {self.id} from Device {self.device.id}'
Expand Down
6 changes: 2 additions & 4 deletions app/main/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from devices.models import Device, DeviceStatus

def get_or_create_station(station_info: dict):
def get_or_create_station(station_info: dict):
'''
station_info dict:
{
Expand All @@ -28,11 +28,9 @@ def get_or_create_station(station_info: dict):
)
if created:
station.device_name = station_info['device']
station.firmware = station_info['firmware']
station.last_update = datetime.datetime.now(datetime.timezone.utc)
station.api_key = station_info['apikey']
station.model = station_info['model']
station.firmware = station_info['firmware']
station.api_key = station_info['apikey']

# add a new DeviceStatus
station_status = DeviceStatus.objects.create(
Expand Down
1 change: 1 addition & 0 deletions app/templates/campaigns/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ <h3 class="mb-0">{% trans "Participants" %}</h3>
<td>{{ user.email }}</td>
<td>
<div class="text-end d-flex flex-column flex-md-row gap-2 justify-content-end">
<a href="{% url 'user-add-device' campaign.pk user.pk %}" class="btn btn-outline-primary btn-sm">{% trans "Add Device" %}</a>
<a href="{% url 'participants-detail' campaign.pk user.pk %}" class="btn btn-primary btn-sm">
<i class="bi bi-eye"></i>
<span class="d-none d-sm-inline">{% trans "Details" %}</span>
Expand Down

0 comments on commit 1f2bc0c

Please sign in to comment.