Wekan - это сервис для ведения проектов. Весь интерфейс выстроен на основе канбан-досок. Вы будто работаете с настоящей доской в кабинете: прикрепляете заметки, разносите их в разные категории, устанавливаете дедлайны и следите за процессом реализации задач.
Импортируем модели из нашего пакета:
from footprint_mongoengine.models import wekan, user
Структура карточки wekan следующая. Основной класс в себе содержит информацию о карточке: статус, время последнего изменения, информацию и пользователей которые записаны в карточку. Здесь есть также два дополнительных класса, один перечисления для поля - какие могут быть статусы у карточки в сервисе, а второй класс - подмодель (по сути структура данных, которая будет является частью модели карточки). Стоит отметить что еще есть поле с ReferenceField. Данное поле ссылается на другие модели (а именно модель User, котороая содержит в себе информацию о пользователе).
class StatusEnum(Enum):
NEW = 'NEW'
IN_PROGRESS = 'IN_PROGRESS'
REVIEW = 'REVIEW'
COMPLETED = 'COMPLETED'
ARCHIVE = 'ARCHIVE'
UNKNOWN = 'UNKNOWN'
class CardInfo(EmbeddedDocument):
hours = IntField(required=True, default=0)
timestamp = DateTimeField(null=True)
assignees = ListField(StringField())
received_at = DateTimeField()
start_at = DateTimeField()
end_at = DateTimeField()
due_at = DateTimeField()
class Card(Document):
meta = {
'collection': 'wekan_cards'
}
users = ListField(ReferenceField(user.User))
board_id = StringField(required=True)
card_id = StringField(required=True)
info = EmbeddedDocumentField(CardInfo, required=True)
status = EnumField(StatusEnum, default=StatusEnum.UNKNOWN)
completed = BooleanField(required=True, default=False)
last_activity = DateTimeField(required=True)
В качестве примера возьмем карточки конкретного пользователя и посмотрим все его карточки.
example_user = example_card.users[0]
for card in wekan.Card.objects(users=example_user):
print(f'card(card_id={card.card_id}, status={card.status}, '
f'completed={card.completed}, last_activity={card.last_activity})')
Вывод:
card(card_id=nZPFPkQTthcNCrtFH, status=StatusEnum.COMPLETED, completed=True, last_activity=2021-12-21 09:16:37.742000)
card(card_id=sBe7jfSv3jNdon4w8, status=StatusEnum.COMPLETED, completed=True, last_activity=2021-12-21 09:14:49.713000)
card(card_id=DbsoLLBBYjahaiRtt, status=StatusEnum.COMPLETED, completed=True, last_activity=2021-12-21 09:15:40.809000)
card(card_id=J9jFdXoXs2qyWzJH9, status=StatusEnum.COMPLETED, completed=True, last_activity=2021-12-21 09:14:56.965000)
card(card_id=ks3PXqcARkf3xwa3L, status=StatusEnum.COMPLETED, completed=True, last_activity=2022-01-28 06:59:46.492000)
card(card_id=L5HaiCMtaTmqBHZCd, status=StatusEnum.COMPLETED, completed=True, last_activity=2022-01-26 13:04:55.589000)
Получим пользователя используя модель из user и посмотрим его карточки.
user_nikita = user.User.objects(slug='naklimin')[0]
print(f'user(slug={user_nikita.slug}, firstname={user_nikita.name.firstname}, '
f'lastname={user_nikita.name.lastname})')
user(slug=naklimin, firstname=Никита, lastname=Климин)
for card in wekan.Card.objects(users=user_nikita):
print(f'card(card_id={card.card_id}, status={card.status}, '
f'hours={card.info.hours}, last_activity={card.last_activity})')
Вывод:
card(card_id=qxjWZYNc8ePMgPoXM, status=StatusEnum.COMPLETED, hours=20, last_activity=2023-02-15 10:05:27.953000)
card(card_id=bzTYbozRdzB9Wtvos, status=StatusEnum.NEW, hours=0, last_activity=2023-02-12 10:59:00.401000)
card(card_id=gwSzomsy5a3ZHo4wE, status=StatusEnum.COMPLETED, hours=10, last_activity=2023-02-15 10:05:56.718000)
card(card_id=jwEezjR4tDN3opKGL, status=StatusEnum.COMPLETED, hours=20, last_activity=2023-01-19 15:30:44.103000)
card(card_id=rLWW5XjB6xmDuAmSh, status=StatusEnum.COMPLETED, hours=25, last_activity=2022-11-25 16:50:21.459000)
card(card_id=k5thuzX6TyjwwbbqL, status=StatusEnum.COMPLETED, hours=25, last_activity=2022-11-25 16:54:25.454000)
card(card_id=RY2v3rA2bXfkFwNvW, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-20 12:08:24.244000)
card(card_id=K2pFvw2rHXtwFioBM, status=StatusEnum.COMPLETED, hours=15, last_activity=2023-01-19 15:31:20.996000)
card(card_id=RkfftvF2AZ2dDyjWQ, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-20 12:09:21.997000)
card(card_id=uSRScYdhmabZ9ZEM8, status=StatusEnum.COMPLETED, hours=30, last_activity=2022-11-13 14:27:58.812000)
card(card_id=WtvLB2z6DSLeXdRS5, status=StatusEnum.COMPLETED, hours=9, last_activity=2022-11-13 14:25:35.786000)
card(card_id=ni7EJiR969Em5EKCf, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-13 14:23:51.091000)
card(card_id=y8TNjJy4SADMMWSNP, status=StatusEnum.ARCHIVE, hours=5, last_activity=2022-09-17 14:16:30.957000)
card(card_id=PQw6JLAjQx4HKJrNo, status=StatusEnum.ARCHIVE, hours=5, last_activity=2022-09-17 14:16:31.885000)
card(card_id=ds5uRMN74TgdFHyc2, status=StatusEnum.ARCHIVE, hours=10, last_activity=2022-09-17 14:16:32.902000)
card(card_id=mjfoBXjjM6mCuEpWm, status=StatusEnum.ARCHIVE, hours=15, last_activity=2022-09-17 14:16:37.791000)
card(card_id=jooNZwSJnfruAm8ge, status=StatusEnum.ARCHIVE, hours=10, last_activity=2022-09-17 14:16:39.032000)
card(card_id=2kLzzcmtB8efDj3uz, status=StatusEnum.ARCHIVE, hours=10, last_activity=2022-09-17 14:16:40.423000)
card(card_id=3CCXT2eYGuRvdXydF, status=StatusEnum.ARCHIVE, hours=20, last_activity=2022-09-17 14:16:50.984000)
card(card_id=do22jDazS5RJkXu3L, status=StatusEnum.ARCHIVE, hours=20, last_activity=2022-09-17 14:16:55.988000)
card(card_id=xbrEbLbbmAMrqXmGb, status=StatusEnum.ARCHIVE, hours=10, last_activity=2022-09-17 14:16:41.580000)
card(card_id=w93xXWPQk82As98Q4, status=StatusEnum.COMPLETED, hours=5, last_activity=2023-02-15 10:08:34.423000)
Усложним запрос:
import datetime
for card in wekan.Card.objects(users=user_nikita,
status=wekan.StatusEnum.COMPLETED,
last_activity__lte=datetime.datetime(day=1, month=1, year=2023),
info__hours__gte=15,
):
print(f'card(card_id={card.card_id}, status={card.status}, '
f'hours={card.info.hours}, last_activity={card.last_activity})')
Вывод:
card(card_id=rLWW5XjB6xmDuAmSh, status=StatusEnum.COMPLETED, hours=25, last_activity=2022-11-25 16:50:21.459000)
card(card_id=k5thuzX6TyjwwbbqL, status=StatusEnum.COMPLETED, hours=25, last_activity=2022-11-25 16:54:25.454000)
card(card_id=RY2v3rA2bXfkFwNvW, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-20 12:08:24.244000)
card(card_id=RkfftvF2AZ2dDyjWQ, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-20 12:09:21.997000)
card(card_id=uSRScYdhmabZ9ZEM8, status=StatusEnum.COMPLETED, hours=30, last_activity=2022-11-13 14:27:58.812000)
card(card_id=ni7EJiR969Em5EKCf, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-13 14:23:51.091000)
Если нужны еще более сложные запросы, можно воспользоваться продвинутым форматом запросов:
from mongoengine.queryset.visitor import Q
for card in wekan.Card.objects(
Q(users=user_nikita) & (Q(status=wekan.StatusEnum.COMPLETED) | Q(info__hours__lt=10))
):
print(f'card(card_id={card.card_id}, status={card.status}, '
f'hours={card.info.hours}, last_activity={card.last_activity})')
Вывод:
card(card_id=qxjWZYNc8ePMgPoXM, status=StatusEnum.COMPLETED, hours=20, last_activity=2023-02-15 10:05:27.953000)
card(card_id=bzTYbozRdzB9Wtvos, status=StatusEnum.NEW, hours=0, last_activity=2023-02-12 10:59:00.401000)
card(card_id=gwSzomsy5a3ZHo4wE, status=StatusEnum.COMPLETED, hours=10, last_activity=2023-02-15 10:05:56.718000)
card(card_id=jwEezjR4tDN3opKGL, status=StatusEnum.COMPLETED, hours=20, last_activity=2023-01-19 15:30:44.103000)
card(card_id=rLWW5XjB6xmDuAmSh, status=StatusEnum.COMPLETED, hours=25, last_activity=2022-11-25 16:50:21.459000)
card(card_id=k5thuzX6TyjwwbbqL, status=StatusEnum.COMPLETED, hours=25, last_activity=2022-11-25 16:54:25.454000)
card(card_id=RY2v3rA2bXfkFwNvW, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-20 12:08:24.244000)
card(card_id=K2pFvw2rHXtwFioBM, status=StatusEnum.COMPLETED, hours=15, last_activity=2023-01-19 15:31:20.996000)
card(card_id=RkfftvF2AZ2dDyjWQ, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-20 12:09:21.997000)
card(card_id=uSRScYdhmabZ9ZEM8, status=StatusEnum.COMPLETED, hours=30, last_activity=2022-11-13 14:27:58.812000)
card(card_id=WtvLB2z6DSLeXdRS5, status=StatusEnum.COMPLETED, hours=9, last_activity=2022-11-13 14:25:35.786000)
card(card_id=ni7EJiR969Em5EKCf, status=StatusEnum.COMPLETED, hours=15, last_activity=2022-11-13 14:23:51.091000)
card(card_id=y8TNjJy4SADMMWSNP, status=StatusEnum.ARCHIVE, hours=5, last_activity=2022-09-17 14:16:30.957000)
card(card_id=PQw6JLAjQx4HKJrNo, status=StatusEnum.ARCHIVE, hours=5, last_activity=2022-09-17 14:16:31.885000)
card(card_id=w93xXWPQk82As98Q4, status=StatusEnum.COMPLETED, hours=5, last_activity=2023-02-15 10:08:34.423000)
Больше информации позапросам к базе данных можно найти по ссылке в официальной документации mongoengine.