def __init__(self, *args):
self._querysets = list(args)
# Mark each QuerySet's Model with the number of the QuerySet it is.
for i, qs in enumerate(self._querysets):
# Generate a Proxy model and then modify that to allow for the same
# Model to be used in multiple QuerySetSequences at once.
qs.model = self._get_model(qs.model)
# Also push this to the Query object since that holds it's own
# reference to QuerySet.model instead of asking the QuerySet for it.
qs.query.model = qs.model
# Actually set the attribute.
setattr(qs.model, '#', i)
# Call super to pick up a variety of properties.
super(QuerySequence, self).__init__(model=None)
python类Model()的实例源码
def __init__(self, *args, **kwargs):
# Create the QuerySequence object where most of the magic happens.
if 'query' not in kwargs:
kwargs['query'] = QuerySequence(*args)
elif args:
raise ValueError(
"Cannot provide args and a 'query' keyword argument.")
# If a particular Model class is not provided, just use the generic
# model class.
# TODO Dynamically generate the fields available in this model via
# introspection of the input QuerySets.
if 'model' not in kwargs:
kwargs['model'] = QuerySetSequenceModel
super(QuerySetSequence, self).__init__(**kwargs)
# Override the iterator that will be used. (Currently used only in
# Django >= 1.11.)
self._iterable_class = SequenceIterable
def get_initial(self):
form_class = self.form_class
if not form_class:
return super(FormMixin, self).get_initial()
# We need a fresh instance to get initial values
form = form_class(
instance=self.instance if isinstance(self.instance, Model) else None
)
res = OrderedDict()
for field_name, field in form.fields.items():
if field.initial:
res[field_name] = self.fields[field_name].to_representation(
field.initial
)
return res
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
form = self.get_form(self.get_form_class())
self.object_list = form.filter_queryset(request, self.object_list)
if form.is_valid():
form_data = dict()
for k, v in form.cleaned_data.iteritems():
if isinstance(v, Model):
v = v.pk
form_data[k] = v
self.request.session[self.SESSION_KEY] = dict(form_data)
context = self.get_context_data(form=form, object_list=self.object_list)
return self.render_to_response(context)
_django_db_models_base.py 文件源码
项目:Tinychat-Bot--Discontinued
作者: Tinychat
项目源码
文件源码
阅读 21
收藏 0
点赞 0
评论 0
def _compile_base_class(self, klass):
if klass is Model:
return
pyamf.ClassAlias._compile_base_class(self, klass)
def _cmp(cls, value1, value2):
"""
Comparison method that takes into account Django's special rules when
ordering by a field that is a model:
1. Try following the default ordering on the related model.
2. Order by the model's primary key, if there is no Meta.ordering.
"""
if isinstance(value1, Model) and isinstance(value2, Model):
field_names = value1._meta.ordering
# Assert that the ordering is the same between different models.
if field_names != value2._meta.ordering:
valid_field_names = (set(cls._get_field_names(value1)) &
set(cls._get_field_names(value2)))
raise FieldError(
"Ordering differs between models. Choices are: %s" %
', '.join(valid_field_names))
# By default, order by the pk.
if not field_names:
field_names = ['pk']
# TODO Figure out if we don't need to generate this comparator every
# time.
return cls._generate_comparator(field_names)(value1, value2)
return cmp(value1, value2)
def decompress(self, value):
# if the value is the actual model instance, don't try to look up model
if isinstance(value, Model):
return [self.display_value(value), value.pk]
elif value:
o = self.model.objects.get(pk=value)
return [self.display_value(o), value]
return ['', None]
def get_cached_form(self, data=None):
if hasattr(self, "_form"):
return self._form
form_class = self.form_class
if form_class:
setattr(self, "_form", form_class(
data,
instance=self.instance if isinstance(self.instance, Model) \
else None)
)
return self._form
return None
def _ordered_iterator(self):
"""An iterator that takes into account the requested ordering."""
# A mapping of iterable to the current item in that iterable. (Remember
# that each QuerySet is already sorted.)
not_empty_qss = [iter(it) for it in self._querysets if it]
values = {it: next(it) for it in not_empty_qss}
# The offset of items returned.
index = 0
# Create a comparison function based on the requested ordering.
_comparator = self._generate_comparator(self.order_by)
def comparator(i1, i2):
# Actually compare the 2nd element in each tuple, the 1st element is
# the generator.
return _comparator(i1[1], i2[1])
comparator = functools.cmp_to_key(comparator)
# If in reverse mode, get the last value instead of the first value from
# ordered_values below.
if self.standard_ordering:
next_value_ind = 0
else:
next_value_ind = -1
# Iterate until all the values are gone.
while values:
# If there's only one iterator left, don't bother sorting.
if len(values) > 1:
# Sort the current values for each iterable.
ordered_values = sorted(values.items(), key=comparator)
# The next ordering item is in the first position, unless we're
# in reverse mode.
qss, value = ordered_values.pop(next_value_ind)
else:
qss, value = list(values.items())[0]
# Return it if we're within the slice of interest.
if self.low_mark <= index:
yield value
index += 1
# We've left the slice of interest, we're done.
if index == self.high_mark:
return
# Iterate the iterable that just lost a value.
try:
values[qss] = next(qss)
except StopIteration:
# This iterator is done, remove it.
del values[qss]
# TODO Inherit from django.db.models.base.Model.