groups
This commit is contained in:
parent
82a15f15c6
commit
715cd274c3
@ -37,6 +37,10 @@ class UserInfo(models.Model):
|
||||
def has_favourite_language(self):
|
||||
return self.favourite_language_id is not None
|
||||
|
||||
@property
|
||||
def verified_friends(self):
|
||||
return User.objects.filter(Q(to_friendship__from_user=self.user) | Q(from_friendship__to_user=self.user))
|
||||
|
||||
@cached_property
|
||||
def friends(self):
|
||||
return Friendship.objects.filter(Q(to_user=self.user) | Q(from_user=self.user)).order_by("verified")
|
||||
|
47
Main/views/GroupView.py
Normal file
47
Main/views/GroupView.py
Normal file
@ -0,0 +1,47 @@
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from SprintLib.BaseView import BaseView, AccessError
|
||||
|
||||
|
||||
class GroupView(BaseView):
|
||||
required_login = True
|
||||
endpoint = 'group'
|
||||
view_file = 'group.html'
|
||||
owner = False
|
||||
|
||||
def pre_handle(self):
|
||||
self.owner = self.entities.group.creator == self.request.user or self.request.user.username in self.entities.group.editors
|
||||
|
||||
def get(self):
|
||||
if self.owner:
|
||||
self.context['possible_users'] = set(self.entities.group.users.all()) | set(self.request.user.userinfo.verified_friends)
|
||||
|
||||
def post_sets_edit(self):
|
||||
if not self.owner:
|
||||
raise AccessError()
|
||||
current_sets = self.entities.group.sets.all()
|
||||
set_ids = [set.id for set in current_sets]
|
||||
for key, value in self.request.POST.items():
|
||||
if key.startswith("set_"):
|
||||
i = int(key.split("_")[1])
|
||||
if i not in set_ids:
|
||||
self.entities.group.sets.add(i)
|
||||
to_delete = [i for i in set_ids if "set_" + str(i) not in self.request.POST]
|
||||
for t in to_delete:
|
||||
self.entities.group.sets.remove(t)
|
||||
return "/group?group_id=" + str(self.entities.group.id)
|
||||
|
||||
def post_users_edit(self):
|
||||
if not self.owner:
|
||||
raise AccessError()
|
||||
current_users = self.entities.group.users.all()
|
||||
users_ids = [user.id for user in current_users]
|
||||
for key, value in self.request.POST.items():
|
||||
if key.startswith("user_"):
|
||||
i = int(key.split("_")[1])
|
||||
if i not in users_ids:
|
||||
self.entities.group.users.add(i)
|
||||
to_delete = [i for i in users_ids if "user_" + str(i) not in self.request.POST]
|
||||
for t in to_delete:
|
||||
self.entities.group.users.remove(t)
|
||||
return "/group?group_id=" + str(self.entities.group.id)
|
@ -1,9 +1,9 @@
|
||||
from random import sample
|
||||
|
||||
from django.db.models import Count, Max
|
||||
from django.db.models import Count, Max, Q
|
||||
from django.utils import timezone
|
||||
|
||||
from Main.models import Task, UserInfo, Solution
|
||||
from Main.models import Task, UserInfo, Solution, Group
|
||||
from SprintLib.BaseView import BaseView
|
||||
|
||||
|
||||
@ -29,3 +29,4 @@ class MainView(BaseView):
|
||||
setattr(task, 'solution', Solution.objects.filter(user=self.request.user, task=task).first())
|
||||
new_tasks = set(Task.objects.filter(public=True)) - set(all_tasks)
|
||||
self.context['new_tasks'] = sample(new_tasks, k=min(5, len(new_tasks)))
|
||||
self.context['groups'] = Group.objects.filter(Q(editors__in=self.request.user.username) | Q(creator=self.request.user) | Q(users=self.request.user)).distinct()
|
||||
|
@ -14,17 +14,11 @@ class SolutionsTableView(BaseView):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.filters = [
|
||||
self.filter_user,
|
||||
self.filter_task,
|
||||
self.filter_set,
|
||||
self.filter_task,
|
||||
]
|
||||
self.queryset = Solution.objects.all()
|
||||
|
||||
def filter_user(self, queryset: QuerySet):
|
||||
if 'username' in self.request.GET:
|
||||
return queryset.filter(user__username=self.request.GET["username"])
|
||||
return queryset
|
||||
|
||||
def filter_task(self, queryset: QuerySet):
|
||||
if 'task_id' in self.request.GET:
|
||||
return queryset.filter(task_id=int(self.request.GET['task_id']))
|
||||
@ -32,7 +26,7 @@ class SolutionsTableView(BaseView):
|
||||
|
||||
def filter_set(self, queryset: QuerySet):
|
||||
if 'set_id' in self.request.GET:
|
||||
return queryset.filter()
|
||||
return queryset.filter(task__settasks__set_id=self.request.GET['set_id']).distinct()
|
||||
return queryset
|
||||
|
||||
def pre_handle(self):
|
||||
|
@ -7,10 +7,6 @@ class SolutionsView(BaseView):
|
||||
view_file = "solutions.html"
|
||||
|
||||
def get(self):
|
||||
self.context["username"] = self.request.GET.get("username")
|
||||
self.context["task_id"] = self.request.GET.get("task_id")
|
||||
if self.context["task_id"]:
|
||||
self.context["task_id"] = int(self.context["task_id"])
|
||||
self.context["set_id"] = self.request.GET.get("set_id")
|
||||
if self.context["set_id"]:
|
||||
self.context["set_id"] = int(self.context["set_id"])
|
||||
self.context['task_id'] = self.request.GET.get('task_id')
|
||||
if not self.context['task_id']:
|
||||
self.context['set_id'] = self.request.GET['set_id']
|
||||
|
@ -19,3 +19,4 @@ from Main.views.ChatView import ChatView
|
||||
from Main.views.ChatWithView import ChatWithView
|
||||
from Main.views.MessagesView import MessagesView
|
||||
from Main.views.SetView import SetView
|
||||
from Main.views.GroupView import GroupView
|
||||
|
85
templates/group.html
Normal file
85
templates/group.html
Normal file
@ -0,0 +1,85 @@
|
||||
{% extends 'base_main.html' %}
|
||||
|
||||
{% block main %}
|
||||
<h2>{{ group.name }}</h2>
|
||||
{% if group.creator %}Владелец группы: <img src="{{ group.creator.userinfo.profile_pic_url }}" width="30px" height="30px" style="border-radius: 50%; margin-right: 10px;"><a href="/account?username={{ group.creator.username }}">{{ group.creator.username }}</a> {% endif %}
|
||||
<hr><hr>
|
||||
<h2>Сеты</h2>
|
||||
{% for set in group.sets.all %}
|
||||
<a href="/set?set_id={{ set.id }}">{{ set.name }}</a><br>
|
||||
{% endfor %}
|
||||
{% if group.creator == user or user.username in user.editors %}
|
||||
<button type="button" class="btn btn-primary" style="margin-top: 20px;" data-toggle="modal" data-target="#example"><i class="fa fa-pencil"></i> Редактировать</button>
|
||||
<div class="modal fade" id="example" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitle" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form method="POST">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitle">Редактировать набор сетов</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="action" value="sets_edit">
|
||||
{% for set in user.userinfo.available_sets %}
|
||||
<input type="checkbox" {% if set in group.sets.all %}checked{% endif %} name="set_{{ set.id }}"> <a href="/set?set_id={{ set.id }}">{{ set.name }}</a><br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-times-circle"></i> Закрыть</button>
|
||||
<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> Установить</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr><hr>
|
||||
<h2>Пользователи</h2>
|
||||
{% for u in group.users.all %}
|
||||
<img src="{{ u.userinfo.profile_pic_url }}" width="30px" height="30px" style="border-radius: 50%; margin-right: 10px;"><a href="/account?username={{ u.username }}">{{ u.username }}</a><br><br>
|
||||
{% endfor %}
|
||||
{% if group.creator == user or user.username in user.editors %}
|
||||
<button type="button" class="btn btn-primary" style="margin-top: 20px;" data-toggle="modal" data-target="#exampleU"><i class="fa fa-pencil"></i> Редактировать</button>
|
||||
<div class="modal fade" id="exampleU" tabindex="-1" role="dialog" aria-labelledby="exampleModalLongTitleU" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form method="POST">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLongTitleU">Редактировать участников группы</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="action" value="users_edit">
|
||||
{% for u in possible_users %}
|
||||
<input type="checkbox" {% if u in group.users.all %}checked{% endif %} name="user_{{ u.id }}"> <a href="/account?username={{ u.username }}">{{ u.username }}</a><br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-times-circle"></i> Закрыть</button>
|
||||
<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> Установить</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<hr><hr>
|
||||
{% endblock %}
|
@ -4,6 +4,9 @@
|
||||
|
||||
{% block main %}
|
||||
<h2>Мои группы</h2>
|
||||
{% for group in groups %}
|
||||
<a href="/group?group_id={{ group.id }}">{{ group.name }}</a>
|
||||
{% endfor %}
|
||||
<hr><hr>
|
||||
<h2>Топ задач сегодня</h2>
|
||||
{% for task in top_tasks_today %}
|
||||
|
@ -44,6 +44,6 @@
|
||||
</tr>
|
||||
</table>
|
||||
{% for set in user.userinfo.available_sets %}
|
||||
<a href="/set?set_id={{ set.id }}">{{ set.name }}</a> {% if set.creator == user %}<a href="/admin/set?set_id={{ set.id }}"><i class="fa fa-pencil"></i> </a>{% endif %}<br>
|
||||
<a href="/set?set_id={{ set.id }}">{{ set.name }}</a> {% if set.creator == user %}<a href="/admin/set?set_id={{ set.id }}"><i class="fa fa-pencil"></i> </a><a href="/solutions?set_id={{ set.id }}"><i class="fa fa-stack-overflow"></i> </a>{% endif %}<br>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
@ -6,7 +6,7 @@
|
||||
page = number;
|
||||
}
|
||||
function doPoll() {
|
||||
jQuery.get('/solutions_table?task_id={{ task.id }}&page=' + page.toString(), function(data) {
|
||||
jQuery.get('/solutions_table?{% if task_id %}task_id={{ task.id }}{% else %}set_id={{ set.id }}{% endif %}&page=' + page.toString(), function(data) {
|
||||
var e = document.getElementById('solutions');
|
||||
if (e.innerHTML !== data)
|
||||
e.innerHTML = data;
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
{% block main %}
|
||||
<h2>Решения</h2>
|
||||
<!--
|
||||
<h4>Фильтр (пока недоступная опция)</h4>
|
||||
<div>
|
||||
<select name="set_id" style="width: 33%">
|
||||
@ -45,5 +46,6 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
-->
|
||||
<div id="solutions"></div>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user