diff --git a/backend/secfit/groups/serializers.py b/backend/secfit/groups/serializers.py
index d58a16e01cb9c5ea34b0b6dd2ad2429b4d43ccc2..8cbed7890ff29ac028934f974bc038e4c8689133 100644
--- a/backend/secfit/groups/serializers.py
+++ b/backend/secfit/groups/serializers.py
@@ -8,7 +8,7 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer):
 
     class Meta:
         model = Group
-        fields = ["owner", "name", "description"]
+        fields = ["id", "owner", "name", "description"]
 
 
 class MembershipSerializer(serializers.ModelSerializer):
@@ -16,4 +16,4 @@ class MembershipSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = Membership
-        fields = ["member", "group"]
+        fields = ["id", "member", "group"]
diff --git a/backend/secfit/groups/urls.py b/backend/secfit/groups/urls.py
index ee77e415f3d108f7d5ce09930a6655df906b0c6e..32d8282ff3fc2c084290855c61f61facc1bd1eae 100644
--- a/backend/secfit/groups/urls.py
+++ b/backend/secfit/groups/urls.py
@@ -1,8 +1,9 @@
 from django.urls import path
-from .views import GroupView, MembershipView
+from .views import GroupView, MembershipView, getGroup
 
 
 urlpatterns = [
     path("api/groups/", GroupView.as_view(), name="group-view"),
     path("api/members/", MembershipView.as_view(), name="membership-view"),
+    path("api/groups/<int:pk>/", getGroup.as_view(), name="updateGroup-view"),
 ]
diff --git a/backend/secfit/groups/views.py b/backend/secfit/groups/views.py
index 75cd8a5a4602726c5aba430044eb83313ee474e8..6bc8ec3e2b1ca90e847e1971fcdd18a8d4603212 100644
--- a/backend/secfit/groups/views.py
+++ b/backend/secfit/groups/views.py
@@ -9,7 +9,7 @@ from rest_framework.filters import OrderingFilter
 
 
 class GroupView(
-    mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView
+    mixins.ListModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, generics.GenericAPIView,
 ):
     queryset = Group.objects.all()
     serializer_class = GroupSerializer
@@ -26,21 +26,34 @@ class GroupView(
         serializer.save(owner=self.request.user)
 
 
-class MembershipView(
+class getGroup(
     mixins.RetrieveModelMixin,
     mixins.UpdateModelMixin,
     mixins.DestroyModelMixin,
     mixins.ListModelMixin,
     generics.GenericAPIView,
 ):
-    queryset = Membership.objects.all()
-    serializer_class = MembershipSerializer
+    queryset = Group.objects.all()
+    serializer_class = GroupSerializer
     # permission_classes = [permissions.IsAuthenticated]
 
-    """
     def get(self, request, *args, **kwargs):
         return self.retrieve(request, *args, **kwargs)
-    """
+
+    def put(self, request, *args, **kwargs):
+        return self.update(request, *args, **kwargs)
+
+
+class MembershipView(
+    mixins.RetrieveModelMixin,
+    mixins.UpdateModelMixin,
+    mixins.DestroyModelMixin,
+    mixins.ListModelMixin,
+    generics.GenericAPIView,
+):
+    queryset = Membership.objects.all()
+    serializer_class = MembershipSerializer
+    # permission_classes = [permissions.IsAuthenticated]
 
     def get(self, request, *args, **kwargs):
         return self.list(request, *args, **kwargs)
diff --git a/frontend/www/group.html b/frontend/www/group.html
index f491a0a8e8776415332c240d1a8113f065ff7d58..4ab650e465b98e14ae9c35da2e8a1d7689f6bbfb 100644
--- a/frontend/www/group.html
+++ b/frontend/www/group.html
@@ -31,8 +31,9 @@
             </div>
             <div class="col-lg-6"></div>
             <div class="col-lg-6">
-                <input type="button" class="btn btn-primary" id="btn-ok-group" value="  OK  ">
-                <input type="button" class="btn btn-secondary" id="btn-cancel-group" value="Cancel">
+                <input type="button" class="btn btn-primary hide" id="btn-ok-group" value="  OK  ">
+                <input type="button" class="btn btn-secondary hide" id="btn-cancel-group" value="Cancel">
+                <input type="button" class="btn btn-primary" id="btn-edit-group" value=" Edit ">
             </div>
             <div class="col-lg-6">
 
diff --git a/frontend/www/scripts/group.js b/frontend/www/scripts/group.js
index adb777226b7ea76fda839b0cc098315a2e9543c2..b8c716d3b7a1fd8abf3026c8bd125358f04e2de2 100644
--- a/frontend/www/scripts/group.js
+++ b/frontend/www/scripts/group.js
@@ -1,12 +1,29 @@
 let cancelButton;
 let okButton;
+let editButton;
 let oldFormData;
 
 function handleCancelButtonDuringCreate() {
     window.location.replace("groups.html");
 }
 
-async function createExercise() {
+function handleCancelButtonDuringEdit() {
+    setReadOnly(true, "#form-group");
+    okButton.className += " hide";
+    cancelButton.className += " hide";
+    editButton.className = editButton.className.replace(" hide", "");
+
+    cancelButton.removeEventListener("click", handleCancelButtonDuringEdit);
+
+    let form = document.querySelector("#form-group");
+    if (oldFormData.has("name")) form.name.value = oldFormData.get("name");
+    if (oldFormData.has("description")) form.description.value = oldFormData.get("description");
+    
+    oldFormData.delete("name");
+    oldFormData.delete("description");
+}
+
+async function createGroup() {
     let form = document.querySelector("#form-group");
     let formData = new FormData(form);
     let body = {"name": formData.get("name"), 
@@ -24,16 +41,95 @@ async function createExercise() {
     }
 }
 
+
+function handleEditGroupButtonClick() {
+    setReadOnly(false, "#form-group");
+
+    editButton.className += " hide";
+    okButton.className = okButton.className.replace(" hide", "");
+    cancelButton.className = cancelButton.className.replace(" hide", "");
+
+    cancelButton.addEventListener("click", handleCancelButtonDuringEdit);
+
+    let form = document.querySelector("#form-group");
+    oldFormData = new FormData(form);
+}
+
+async function retrieveGroup(id) {
+    let response = await sendRequest("GET", `${HOST}/api/groups/${id}/`);
+
+    console.log(response.ok)
+
+    if (!response.ok) {
+        let data = await response.json();
+        let alert = createAlert("Could not retrieve group data!", data);
+        document.body.prepend(alert);
+    } else {
+        let groupData = await response.json();
+        let form = document.querySelector("#form-group");
+        let formData = new FormData(form);
+
+        for (let key of formData.keys()) {
+            let selector
+            selector = `input[name="${key}"], textarea[name="${key}"]`;
+            let input = form.querySelector(selector);
+            let newVal = groupData[key];
+            input.value = newVal;
+        }
+    }
+}
+
+async function updateGroup(id) {
+    let form = document.querySelector("#form-group");
+    let formData = new FormData(form);
+
+    let body = {"name": formData.get("name"), 
+                "description": formData.get("description"),
+                };
+    let response = await sendRequest("PUT", `${HOST}/api/groups/${id}/`, body);
+
+    if (!response.ok) {
+        let data = await response.json();
+        let alert = createAlert(`Could not update group ${id}`, data);
+        document.body.prepend(alert);
+    } else {
+        setReadOnly(true, "#form-group");
+        okButton.className += " hide";
+        cancelButton.className += " hide";
+        editButton.className = editButton.className.replace(" hide", "");
+    
+        cancelButton.removeEventListener("click", handleCancelButtonDuringEdit);
+        
+        oldFormData.delete("name");
+        oldFormData.delete("description");
+    }
+}
+
 window.addEventListener("DOMContentLoaded", async () => {
     cancelButton = document.querySelector("#btn-cancel-group");
     okButton = document.querySelector("#btn-ok-group");
+    editButton = document.querySelector("#btn-edit-group");
     oldFormData = null;
 
-    setReadOnly(false, "#form-group");
+    const urlParams = new URLSearchParams(window.location.search);
 
-    okButton.className = okButton.className.replace(" hide", "");
-    cancelButton.className = cancelButton.className.replace(" hide", "");
+    // view/edit
+    if (urlParams.has('id')) {
+        const groupId = urlParams.get('id');
+        await retrieveGroup(groupId);
+
+        editButton.addEventListener("click", handleEditGroupButtonClick);
+        okButton.addEventListener("click", (async (id) => await updateGroup(id)).bind(undefined, groupId));
+    } 
+    //create
+    else {
+        setReadOnly(false, "#form-group");
 
-    okButton.addEventListener("click", async () => await createExercise());
-    cancelButton.addEventListener("click", handleCancelButtonDuringCreate);
+        editButton.className += " hide";
+        okButton.className = okButton.className.replace(" hide", "");
+        cancelButton.className = cancelButton.className.replace(" hide", "");
+
+        okButton.addEventListener("click", async () => await createGroup());
+        cancelButton.addEventListener("click", handleCancelButtonDuringCreate);
+    }
 });
\ No newline at end of file
diff --git a/frontend/www/scripts/groups.js b/frontend/www/scripts/groups.js
index b15df62715851ccd568fa700a7f4a20e9cf56eed..4e839b7635c2d8091dfbaf4b37a4507edfba15fb 100644
--- a/frontend/www/scripts/groups.js
+++ b/frontend/www/scripts/groups.js
@@ -9,7 +9,7 @@ async function fetchGroups(request) {
         let exerciseTemplate = document.querySelector("#template-group");
         groups.forEach(group => {
             const exerciseAnchor = exerciseTemplate.content.firstElementChild.cloneNode(true);
-            exerciseAnchor.href = `exercise.html?id=${group.id}`;
+            exerciseAnchor.href = `group.html?id=${group.id}`;
 
             const h5 = exerciseAnchor.querySelector("h5");
             h5.textContent = group.name;
diff --git a/frontend/www/scripts/navbar.js b/frontend/www/scripts/navbar.js
index 8dec8c1a20089ea9bbb85e5df99001473ec64c2c..15bf24e7fcb91a549370f050eb9c53e5a284d97b 100644
--- a/frontend/www/scripts/navbar.js
+++ b/frontend/www/scripts/navbar.js
@@ -19,6 +19,7 @@ class NavBar extends HTMLElement {
                 <a class="nav-link hide" id="nav-mycoach" href="mycoach.html">Coach</a>
                 <a class="nav-link hide" id="nav-myathletes" href="myathletes.html">Athletes</a>
                 <a class="nav-link hide" id="nav-meals" href="meals.html">Meal registration</a>
+                <a class="nav-link hide" id="nav-groups" href="groups.html">Groups</a>
                 <hr>
             </div>
             <div class="my-2 my-lg-0 me-5">
diff --git a/frontend/www/scripts/scripts.js b/frontend/www/scripts/scripts.js
index 9bfc1efb688400bcabfa9457b05be97f8dbd9c92..1cd174452b91bba96cb5840dd42a2ee9996e923e 100644
--- a/frontend/www/scripts/scripts.js
+++ b/frontend/www/scripts/scripts.js
@@ -24,6 +24,8 @@ function updateNavBar() {
     makeNavLinkActive("nav-myathletes");
   } else if (window.location.pathname == "/meals.html") {
     makeNavLinkActive("nav-myathletes");
+  } else if (window.location.pathname == "/groups.html") {
+    makeNavLinkActive("nav-groups");
   }
 
   if (isUserAuthenticated()) {
@@ -35,6 +37,7 @@ function updateNavBar() {
     document.querySelector('a[href="exercises.html"').classList.remove("hide");
     document.querySelector('a[href="myathletes.html"').classList.remove("hide");
     document.querySelector('a[href="meals.html"').classList.remove("hide");
+    document.querySelector('a[href="groups.html"').classList.remove("hide");
   } else {
     document.getElementById("btn-login-nav").classList.remove("hide");
     document.getElementById("btn-register").classList.remove("hide");