Я просто экспериментирую с тем, как «динамически распределить функции набора запросов», и мне хотелось бы знать о проблемах производительности, с которыми я мог бы столкнуться позже.
Мои наборы запросов работают отлично, но я немного скептически к ним отношусь .
Пожалуйста, посмотрите на мой код:
settings.py:
...
TODO_PRIORITY = (
('LOW', 'Low'),
('MEDIUM', 'Medium'),
('HIGH', 'High'),
)
...
models.py
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from .manager import TodoManager
from django.conf import settings
User = get_user_model()
TODO_PRIORITY = getattr(settings, 'TODO_PRIORITY', None)
assert TODO_PRIORITY is not None, "Your settings file is missing `TODO_PRIORITY` variable"
assert isinstance(TODO_PRIORITY, tuple), "`TODO_PRIORITY` must be a tuple"
# Create your models here.
class Todo(models.Model):
class Meta:
ordering = ('start_time',)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="todos")
content = models.TextField(max_length=500, blank=False)
start_time = models.DateTimeField(default=timezone.now)
end_time = models.DateTimeField(blank=False)
priority = models.CharField(max_length=6, choices=TODO_PRIORITY, default="MEDIUM")
timestamp = models.DateTimeField(auto_now_add=True)
objects = TodoManager()
@property
def todo_id(self):
return self.id
manager.py
from django.db import models
from django.utils import timezone
from django.conf import settings
now = timezone.now()
today = now.replace(hour=0, minute=0, second=0, microsecond=0)
tomorrow = today + timezone.timedelta(days=1)
TODO_PRIORITY = getattr(settings, 'TODO_PRIORITY', None)
assert TODO_PRIORITY is not None, "Your settings file is missing `TODO_PRIORITY` variable."
assert isinstance(TODO_PRIORITY, tuple), "`TODO_PRIORITY` must be a tuple."
class TodoQueryset(models.query.QuerySet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for priority in TODO_PRIORITY:
self.add__fn(priority)
def add__fn(self, object):
assert isinstance(object, tuple), '`TODO_PRIORITY` object must be a tuple.'
fn_name = object[1].lower()
def fn():
return self.filter(priority=object[0].upper(), start_time__gte=today)
setattr(self, fn_name, fn)
class TodoManager(models.Manager):
_queryset_class = TodoQueryset
ОБНОВЛЕНИЕ 0
Я заметил, что __init__()
работает несколько раз, как я могу избежать этого?
=> я спрашивал вокруг, и это кажется нормальным поведением, потому что django использует filter()
затем get()
ОБНОВЛЕНИЕ 1
У меня наконец-то менеджер, который нашел способ автоматического создания методов класса, и я опубликую ответ через минуту