mirror of
https://github.com/django/django.git
synced 2024-12-22 09:05:43 +00:00
Fixed E128 flake8 warnings in django/.
This commit is contained in:
parent
2956e2f5e3
commit
df8d8d4292
@ -297,8 +297,10 @@ class Apps(object):
|
||||
available = set(available)
|
||||
installed = set(app_config.name for app_config in self.get_app_configs())
|
||||
if not available.issubset(installed):
|
||||
raise ValueError("Available apps isn't a subset of installed "
|
||||
"apps, extra apps: %s" % ", ".join(available - installed))
|
||||
raise ValueError(
|
||||
"Available apps isn't a subset of installed apps, extra apps: %s"
|
||||
% ", ".join(available - installed)
|
||||
)
|
||||
|
||||
self.stored_app_configs.append(self.app_configs)
|
||||
self.app_configs = OrderedDict(
|
||||
|
@ -108,8 +108,7 @@ class Settings(BaseSettings):
|
||||
|
||||
if (setting in tuple_settings and
|
||||
not isinstance(setting_value, (list, tuple))):
|
||||
raise ImproperlyConfigured("The %s setting must be a list or a tuple. "
|
||||
"Please fix your settings." % setting)
|
||||
raise ImproperlyConfigured("The %s setting must be a list or a tuple. " % setting)
|
||||
setattr(self, setting, setting_value)
|
||||
self._explicit_settings.add(setting)
|
||||
|
||||
|
@ -20,12 +20,12 @@ compress all jQuery-based files of the admin app. Requires the Google Closure
|
||||
Compiler library and Java version 6 or later."""
|
||||
parser = argparse.ArgumentParser(description=description)
|
||||
parser.add_argument('file', nargs='*')
|
||||
parser.add_argument("-c", dest="compiler", default="~/bin/compiler.jar",
|
||||
help="path to Closure Compiler jar file")
|
||||
parser.add_argument("-v", "--verbose",
|
||||
action="store_true", dest="verbose")
|
||||
parser.add_argument("-q", "--quiet",
|
||||
action="store_false", dest="verbose")
|
||||
parser.add_argument(
|
||||
"-c", dest="compiler", default="~/bin/compiler.jar",
|
||||
help="path to Closure Compiler jar file",
|
||||
)
|
||||
parser.add_argument("-v", "--verbose", action="store_true", dest="verbose")
|
||||
parser.add_argument("-q", "--quiet", action="store_false", dest="verbose")
|
||||
options = parser.parse_args()
|
||||
|
||||
compiler = closure_compiler if closure_compiler else os.path.expanduser(options.compiler)
|
||||
@ -38,8 +38,10 @@ Compiler library and Java version 6 or later."""
|
||||
if not options.file:
|
||||
if options.verbose:
|
||||
sys.stdout.write("No filenames given; defaulting to admin scripts\n")
|
||||
files = [os.path.join(js_path, f) for f in [
|
||||
"actions.js", "collapse.js", "inlines.js", "prepopulate.js"]]
|
||||
files = [
|
||||
os.path.join(js_path, f) for f in
|
||||
["actions.js", "collapse.js", "inlines.js", "prepopulate.js"]
|
||||
]
|
||||
else:
|
||||
files = options.file
|
||||
|
||||
|
@ -155,8 +155,7 @@ class FieldListFilter(ListFilter):
|
||||
for test, list_filter_class in cls._field_list_filters:
|
||||
if not test(field):
|
||||
continue
|
||||
return list_filter_class(field, request, params,
|
||||
model, model_admin, field_path=field_path)
|
||||
return list_filter_class(field, request, params, model, model_admin, field_path=field_path)
|
||||
|
||||
|
||||
class RelatedFieldListFilter(FieldListFilter):
|
||||
@ -200,8 +199,10 @@ class RelatedFieldListFilter(FieldListFilter):
|
||||
def choices(self, changelist):
|
||||
yield {
|
||||
'selected': self.lookup_val is None and not self.lookup_val_isnull,
|
||||
'query_string': changelist.get_query_string({},
|
||||
[self.lookup_kwarg, self.lookup_kwarg_isnull]),
|
||||
'query_string': changelist.get_query_string(
|
||||
{},
|
||||
[self.lookup_kwarg, self.lookup_kwarg_isnull]
|
||||
),
|
||||
'display': _('All'),
|
||||
}
|
||||
for pk_val, val in self.lookup_choices:
|
||||
@ -230,8 +231,7 @@ class BooleanFieldListFilter(FieldListFilter):
|
||||
self.lookup_kwarg2 = '%s__isnull' % field_path
|
||||
self.lookup_val = request.GET.get(self.lookup_kwarg)
|
||||
self.lookup_val2 = request.GET.get(self.lookup_kwarg2)
|
||||
super(BooleanFieldListFilter, self).__init__(field,
|
||||
request, params, model, model_admin, field_path)
|
||||
super(BooleanFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path)
|
||||
|
||||
def expected_parameters(self):
|
||||
return [self.lookup_kwarg, self.lookup_kwarg2]
|
||||
@ -257,8 +257,10 @@ class BooleanFieldListFilter(FieldListFilter):
|
||||
'display': _('Unknown'),
|
||||
}
|
||||
|
||||
FieldListFilter.register(lambda f: isinstance(f,
|
||||
(models.BooleanField, models.NullBooleanField)), BooleanFieldListFilter)
|
||||
FieldListFilter.register(
|
||||
lambda f: isinstance(f, (models.BooleanField, models.NullBooleanField)),
|
||||
BooleanFieldListFilter
|
||||
)
|
||||
|
||||
|
||||
class ChoicesFieldListFilter(FieldListFilter):
|
||||
@ -290,8 +292,7 @@ FieldListFilter.register(lambda f: bool(f.choices), ChoicesFieldListFilter)
|
||||
class DateFieldListFilter(FieldListFilter):
|
||||
def __init__(self, field, request, params, model, model_admin, field_path):
|
||||
self.field_generic = '%s__' % field_path
|
||||
self.date_params = {k: v for k, v in params.items()
|
||||
if k.startswith(self.field_generic)}
|
||||
self.date_params = {k: v for k, v in params.items() if k.startswith(self.field_generic)}
|
||||
|
||||
now = timezone.now()
|
||||
# When time zone support is enabled, convert "now" to the user's time
|
||||
@ -387,8 +388,7 @@ class AllValuesFieldListFilter(FieldListFilter):
|
||||
def choices(self, changelist):
|
||||
yield {
|
||||
'selected': self.lookup_val is None and self.lookup_val_isnull is None,
|
||||
'query_string': changelist.get_query_string({},
|
||||
[self.lookup_kwarg, self.lookup_kwarg_isnull]),
|
||||
'query_string': changelist.get_query_string({}, [self.lookup_kwarg, self.lookup_kwarg_isnull]),
|
||||
'display': _('All'),
|
||||
}
|
||||
include_none = False
|
||||
|
@ -10,9 +10,10 @@ class AdminAuthenticationForm(AuthenticationForm):
|
||||
A custom authentication form used in the admin app.
|
||||
"""
|
||||
error_messages = {
|
||||
'invalid_login': _("Please enter the correct %(username)s and password "
|
||||
"for a staff account. Note that both fields may be "
|
||||
"case-sensitive."),
|
||||
'invalid_login': _(
|
||||
"Please enter the correct %(username)s and password for a staff "
|
||||
"account. Note that both fields may be case-sensitive."
|
||||
),
|
||||
}
|
||||
required_css_class = 'required'
|
||||
|
||||
|
@ -25,8 +25,12 @@ ACTION_CHECKBOX_NAME = '_selected_action'
|
||||
|
||||
class ActionForm(forms.Form):
|
||||
action = forms.ChoiceField(label=_('Action:'))
|
||||
select_across = forms.BooleanField(label='', required=False, initial=0,
|
||||
widget=forms.HiddenInput({'class': 'select-across'}))
|
||||
select_across = forms.BooleanField(
|
||||
label='',
|
||||
required=False,
|
||||
initial=0,
|
||||
widget=forms.HiddenInput({'class': 'select-across'}),
|
||||
)
|
||||
|
||||
checkbox = forms.CheckboxInput({'class': 'action-select'}, lambda value: False)
|
||||
|
||||
@ -62,7 +66,7 @@ class AdminForm(object):
|
||||
|
||||
class Fieldset(object):
|
||||
def __init__(self, form, name=None, readonly_fields=(), fields=(), classes=(),
|
||||
description=None, model_admin=None):
|
||||
description=None, model_admin=None):
|
||||
self.form = form
|
||||
self.name, self.fields = name, fields
|
||||
self.classes = ' '.join(classes)
|
||||
@ -73,9 +77,11 @@ class Fieldset(object):
|
||||
def _media(self):
|
||||
if 'collapse' in self.classes:
|
||||
extra = '' if settings.DEBUG else '.min'
|
||||
js = ['vendor/jquery/jquery%s.js' % extra,
|
||||
'jquery.init.js',
|
||||
'collapse%s.js' % extra]
|
||||
js = [
|
||||
'vendor/jquery/jquery%s.js' % extra,
|
||||
'jquery.init.js',
|
||||
'collapse%s.js' % extra,
|
||||
]
|
||||
return forms.Media(js=['admin/js/%s' % url for url in js])
|
||||
return forms.Media()
|
||||
media = property(_media)
|
||||
@ -92,9 +98,10 @@ class Fieldline(object):
|
||||
self.fields = [field]
|
||||
else:
|
||||
self.fields = field
|
||||
self.has_visible_field = not all(field in self.form.fields and
|
||||
self.form.fields[field].widget.is_hidden
|
||||
for field in self.fields)
|
||||
self.has_visible_field = not all(
|
||||
field in self.form.fields and self.form.fields[field].widget.is_hidden
|
||||
for field in self.fields
|
||||
)
|
||||
self.model_admin = model_admin
|
||||
if readonly_fields is None:
|
||||
readonly_fields = ()
|
||||
@ -103,15 +110,15 @@ class Fieldline(object):
|
||||
def __iter__(self):
|
||||
for i, field in enumerate(self.fields):
|
||||
if field in self.readonly_fields:
|
||||
yield AdminReadonlyField(self.form, field, is_first=(i == 0),
|
||||
model_admin=self.model_admin)
|
||||
yield AdminReadonlyField(self.form, field, is_first=(i == 0), model_admin=self.model_admin)
|
||||
else:
|
||||
yield AdminField(self.form, field, is_first=(i == 0))
|
||||
|
||||
def errors(self):
|
||||
return mark_safe(
|
||||
'\n'.join(self.form[f].errors.as_ul()
|
||||
for f in self.fields if f not in self.readonly_fields).strip('\n')
|
||||
'\n'.join(
|
||||
self.form[f].errors.as_ul() for f in self.fields if f not in self.readonly_fields
|
||||
).strip('\n')
|
||||
)
|
||||
|
||||
|
||||
@ -135,8 +142,10 @@ class AdminField(object):
|
||||
attrs = {'class': ' '.join(classes)} if classes else {}
|
||||
# checkboxes should not have a label suffix as the checkbox appears
|
||||
# to the left of the label.
|
||||
return self.field.label_tag(contents=mark_safe(contents), attrs=attrs,
|
||||
label_suffix='' if self.is_checkbox else None)
|
||||
return self.field.label_tag(
|
||||
contents=mark_safe(contents), attrs=attrs,
|
||||
label_suffix='' if self.is_checkbox else None,
|
||||
)
|
||||
|
||||
def errors(self):
|
||||
return mark_safe(self.field.errors.as_ul())
|
||||
@ -225,7 +234,7 @@ class InlineAdminFormSet(object):
|
||||
A wrapper around an inline formset for use in the admin system.
|
||||
"""
|
||||
def __init__(self, inline, formset, fieldsets, prepopulated_fields=None,
|
||||
readonly_fields=None, model_admin=None):
|
||||
readonly_fields=None, model_admin=None):
|
||||
self.opts = inline
|
||||
self.formset = formset
|
||||
self.fieldsets = fieldsets
|
||||
@ -241,16 +250,21 @@ class InlineAdminFormSet(object):
|
||||
def __iter__(self):
|
||||
for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()):
|
||||
view_on_site_url = self.opts.get_view_on_site_url(original)
|
||||
yield InlineAdminForm(self.formset, form, self.fieldsets,
|
||||
self.prepopulated_fields, original, self.readonly_fields,
|
||||
model_admin=self.opts, view_on_site_url=view_on_site_url)
|
||||
yield InlineAdminForm(
|
||||
self.formset, form, self.fieldsets, self.prepopulated_fields,
|
||||
original, self.readonly_fields, model_admin=self.opts,
|
||||
view_on_site_url=view_on_site_url,
|
||||
)
|
||||
for form in self.formset.extra_forms:
|
||||
yield InlineAdminForm(self.formset, form, self.fieldsets,
|
||||
self.prepopulated_fields, None, self.readonly_fields,
|
||||
model_admin=self.opts)
|
||||
yield InlineAdminForm(self.formset, self.formset.empty_form,
|
||||
yield InlineAdminForm(
|
||||
self.formset, form, self.fieldsets, self.prepopulated_fields,
|
||||
None, self.readonly_fields, model_admin=self.opts,
|
||||
)
|
||||
yield InlineAdminForm(
|
||||
self.formset, self.formset.empty_form,
|
||||
self.fieldsets, self.prepopulated_fields, None,
|
||||
self.readonly_fields, model_admin=self.opts)
|
||||
self.readonly_fields, model_admin=self.opts,
|
||||
)
|
||||
|
||||
def fields(self):
|
||||
fk = getattr(self.formset, "fk", None)
|
||||
@ -260,9 +274,7 @@ class InlineAdminFormSet(object):
|
||||
if field_name in self.readonly_fields:
|
||||
yield {
|
||||
'label': label_for_field(field_name, self.opts.model, self.opts),
|
||||
'widget': {
|
||||
'is_hidden': False
|
||||
},
|
||||
'widget': {'is_hidden': False},
|
||||
'required': False,
|
||||
'help_text': help_text_for_field(field_name, self.opts.model),
|
||||
}
|
||||
@ -304,19 +316,20 @@ class InlineAdminForm(AdminForm):
|
||||
A wrapper around an inline form for use in the admin system.
|
||||
"""
|
||||
def __init__(self, formset, form, fieldsets, prepopulated_fields, original,
|
||||
readonly_fields=None, model_admin=None, view_on_site_url=None):
|
||||
readonly_fields=None, model_admin=None, view_on_site_url=None):
|
||||
self.formset = formset
|
||||
self.model_admin = model_admin
|
||||
self.original = original
|
||||
self.show_url = original and view_on_site_url is not None
|
||||
self.absolute_url = view_on_site_url
|
||||
super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields,
|
||||
readonly_fields, model_admin)
|
||||
super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields, readonly_fields, model_admin)
|
||||
|
||||
def __iter__(self):
|
||||
for name, options in self.fieldsets:
|
||||
yield InlineFieldset(self.formset, self.form, name,
|
||||
self.readonly_fields, model_admin=self.model_admin, **options)
|
||||
yield InlineFieldset(
|
||||
self.formset, self.form, name, self.readonly_fields,
|
||||
model_admin=self.model_admin, **options
|
||||
)
|
||||
|
||||
def needs_explicit_pk_field(self):
|
||||
# Auto fields are editable (oddly), so need to check for auto or non-editable pk
|
||||
@ -358,8 +371,7 @@ class InlineFieldset(Fieldset):
|
||||
for field in self.fields:
|
||||
if fk and fk.name == field:
|
||||
continue
|
||||
yield Fieldline(self.form, field, self.readonly_fields,
|
||||
model_admin=self.model_admin)
|
||||
yield Fieldline(self.form, field, self.readonly_fields, model_admin=self.model_admin)
|
||||
|
||||
|
||||
class AdminErrorList(forms.utils.ErrorList):
|
||||
|
@ -214,8 +214,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
|
||||
"""
|
||||
db = kwargs.get('using')
|
||||
if db_field.name in self.raw_id_fields:
|
||||
kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.remote_field,
|
||||
self.admin_site, using=db)
|
||||
kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.remote_field, self.admin_site, using=db)
|
||||
elif db_field.name in self.radio_fields:
|
||||
kwargs['widget'] = widgets.AdminRadioSelect(attrs={
|
||||
'class': get_ul_class(self.radio_fields[db_field.name]),
|
||||
@ -240,8 +239,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
|
||||
db = kwargs.get('using')
|
||||
|
||||
if db_field.name in self.raw_id_fields:
|
||||
kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.remote_field,
|
||||
self.admin_site, using=db)
|
||||
kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.remote_field, self.admin_site, using=db)
|
||||
elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
|
||||
kwargs['widget'] = widgets.FilteredSelectMultiple(
|
||||
db_field.verbose_name,
|
||||
@ -639,8 +637,10 @@ class ModelAdmin(BaseModelAdmin):
|
||||
try:
|
||||
return modelform_factory(self.model, **defaults)
|
||||
except FieldError as e:
|
||||
raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
|
||||
% (e, self.__class__.__name__))
|
||||
raise FieldError(
|
||||
'%s. Check fields/fieldsets/exclude attributes of class %s.'
|
||||
% (e, self.__class__.__name__)
|
||||
)
|
||||
|
||||
def get_changelist(self, request, **kwargs):
|
||||
"""
|
||||
@ -686,9 +686,10 @@ class ModelAdmin(BaseModelAdmin):
|
||||
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
|
||||
}
|
||||
defaults.update(kwargs)
|
||||
return modelformset_factory(self.model,
|
||||
self.get_changelist_form(request), extra=0,
|
||||
fields=self.list_editable, **defaults)
|
||||
return modelformset_factory(
|
||||
self.model, self.get_changelist_form(request), extra=0,
|
||||
fields=self.list_editable, **defaults
|
||||
)
|
||||
|
||||
def get_formsets_with_inlines(self, request, obj=None):
|
||||
"""
|
||||
@ -974,7 +975,6 @@ class ModelAdmin(BaseModelAdmin):
|
||||
compatibility. For convenience, it accepts the `level` argument as
|
||||
a string rather than the usual level number.
|
||||
"""
|
||||
|
||||
if not isinstance(level, int):
|
||||
# attempt to get the level if passed a string
|
||||
try:
|
||||
@ -982,11 +982,12 @@ class ModelAdmin(BaseModelAdmin):
|
||||
except AttributeError:
|
||||
levels = messages.constants.DEFAULT_TAGS.values()
|
||||
levels_repr = ', '.join('`%s`' % l for l in levels)
|
||||
raise ValueError('Bad message level string: `%s`. '
|
||||
'Possible values are: %s' % (level, levels_repr))
|
||||
raise ValueError(
|
||||
'Bad message level string: `%s`. Possible values are: %s'
|
||||
% (level, levels_repr)
|
||||
)
|
||||
|
||||
messages.add_message(request, level, message, extra_tags=extra_tags,
|
||||
fail_silently=fail_silently)
|
||||
messages.add_message(request, level, message, extra_tags=extra_tags, fail_silently=fail_silently)
|
||||
|
||||
def save_form(self, request, form, change):
|
||||
"""
|
||||
@ -1323,23 +1324,26 @@ class ModelAdmin(BaseModelAdmin):
|
||||
'popup_response_data': popup_response_data,
|
||||
})
|
||||
|
||||
self.message_user(request,
|
||||
self.message_user(
|
||||
request,
|
||||
_('The %(name)s "%(obj)s" was deleted successfully.') % {
|
||||
'name': force_text(opts.verbose_name),
|
||||
'obj': force_text(obj_display),
|
||||
}, messages.SUCCESS)
|
||||
},
|
||||
messages.SUCCESS,
|
||||
)
|
||||
|
||||
if self.has_change_permission(request, None):
|
||||
post_url = reverse('admin:%s_%s_changelist' %
|
||||
(opts.app_label, opts.model_name),
|
||||
current_app=self.admin_site.name)
|
||||
post_url = reverse(
|
||||
'admin:%s_%s_changelist' % (opts.app_label, opts.model_name),
|
||||
current_app=self.admin_site.name,
|
||||
)
|
||||
preserved_filters = self.get_preserved_filters(request)
|
||||
post_url = add_preserved_filters(
|
||||
{'preserved_filters': preserved_filters, 'opts': opts}, post_url
|
||||
)
|
||||
else:
|
||||
post_url = reverse('admin:index',
|
||||
current_app=self.admin_site.name)
|
||||
post_url = reverse('admin:index', current_app=self.admin_site.name)
|
||||
return HttpResponseRedirect(post_url)
|
||||
|
||||
def render_delete_form(self, request, context):
|
||||
@ -1353,22 +1357,26 @@ class ModelAdmin(BaseModelAdmin):
|
||||
media=self.media,
|
||||
)
|
||||
|
||||
return TemplateResponse(request,
|
||||
return TemplateResponse(
|
||||
request,
|
||||
self.delete_confirmation_template or [
|
||||
"admin/{}/{}/delete_confirmation.html".format(app_label, opts.model_name),
|
||||
"admin/{}/delete_confirmation.html".format(app_label),
|
||||
"admin/delete_confirmation.html"
|
||||
], context)
|
||||
"admin/delete_confirmation.html",
|
||||
],
|
||||
context,
|
||||
)
|
||||
|
||||
def get_inline_formsets(self, request, formsets, inline_instances,
|
||||
obj=None):
|
||||
def get_inline_formsets(self, request, formsets, inline_instances, obj=None):
|
||||
inline_admin_formsets = []
|
||||
for inline, formset in zip(inline_instances, formsets):
|
||||
fieldsets = list(inline.get_fieldsets(request, obj))
|
||||
readonly = list(inline.get_readonly_fields(request, obj))
|
||||
prepopulated = dict(inline.get_prepopulated_fields(request, obj))
|
||||
inline_admin_formset = helpers.InlineAdminFormSet(inline, formset,
|
||||
fieldsets, prepopulated, readonly, model_admin=self)
|
||||
inline_admin_formset = helpers.InlineAdminFormSet(
|
||||
inline, formset, fieldsets, prepopulated, readonly,
|
||||
model_admin=self,
|
||||
)
|
||||
inline_admin_formsets.append(inline_admin_formset)
|
||||
return inline_admin_formsets
|
||||
|
||||
@ -1462,7 +1470,8 @@ class ModelAdmin(BaseModelAdmin):
|
||||
for inline_formset in inline_formsets:
|
||||
media = media + inline_formset.media
|
||||
|
||||
context = dict(self.admin_site.each_context(request),
|
||||
context = dict(
|
||||
self.admin_site.each_context(request),
|
||||
title=(_('Add %s') if add else _('Change %s')) % force_text(opts.verbose_name),
|
||||
adminform=adminForm,
|
||||
object_id=object_id,
|
||||
@ -1519,11 +1528,12 @@ class ModelAdmin(BaseModelAdmin):
|
||||
|
||||
ChangeList = self.get_changelist(request)
|
||||
try:
|
||||
cl = ChangeList(request, self.model, list_display,
|
||||
cl = ChangeList(
|
||||
request, self.model, list_display,
|
||||
list_display_links, list_filter, self.date_hierarchy,
|
||||
search_fields, list_select_related, self.list_per_page,
|
||||
self.list_max_show_all, self.list_editable, self)
|
||||
|
||||
self.list_max_show_all, self.list_editable, self,
|
||||
)
|
||||
except IncorrectLookupParameters:
|
||||
# Wacky lookup parameters were given, so redirect to the main
|
||||
# changelist page, without parameters, and pass an 'invalid=1'
|
||||
@ -1596,11 +1606,15 @@ class ModelAdmin(BaseModelAdmin):
|
||||
name = force_text(opts.verbose_name)
|
||||
else:
|
||||
name = force_text(opts.verbose_name_plural)
|
||||
msg = ungettext("%(count)s %(name)s was changed successfully.",
|
||||
"%(count)s %(name)s were changed successfully.",
|
||||
changecount) % {'count': changecount,
|
||||
'name': name,
|
||||
'obj': force_text(obj)}
|
||||
msg = ungettext(
|
||||
"%(count)s %(name)s was changed successfully.",
|
||||
"%(count)s %(name)s were changed successfully.",
|
||||
changecount
|
||||
) % {
|
||||
'count': changecount,
|
||||
'name': name,
|
||||
'obj': force_text(obj),
|
||||
}
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
@ -1623,8 +1637,11 @@ class ModelAdmin(BaseModelAdmin):
|
||||
else:
|
||||
action_form = None
|
||||
|
||||
selection_note_all = ungettext('%(total_count)s selected',
|
||||
'All %(total_count)s selected', cl.result_count)
|
||||
selection_note_all = ungettext(
|
||||
'%(total_count)s selected',
|
||||
'All %(total_count)s selected',
|
||||
cl.result_count
|
||||
)
|
||||
|
||||
context = dict(
|
||||
self.admin_site.each_context(request),
|
||||
@ -1744,7 +1761,8 @@ class ModelAdmin(BaseModelAdmin):
|
||||
content_type=get_content_type_for_model(model)
|
||||
).select_related().order_by('action_time')
|
||||
|
||||
context = dict(self.admin_site.each_context(request),
|
||||
context = dict(
|
||||
self.admin_site.each_context(request),
|
||||
title=_('Change history: %s') % force_text(obj),
|
||||
action_list=action_list,
|
||||
module_name=capfirst(force_text(opts.verbose_name_plural)),
|
||||
|
@ -84,8 +84,9 @@ class AdminSite(object):
|
||||
model_or_iterable = [model_or_iterable]
|
||||
for model in model_or_iterable:
|
||||
if model._meta.abstract:
|
||||
raise ImproperlyConfigured('The model %s is abstract, so it '
|
||||
'cannot be registered with admin.' % model.__name__)
|
||||
raise ImproperlyConfigured(
|
||||
'The model %s is abstract, so it cannot be registered with admin.' % model.__name__
|
||||
)
|
||||
|
||||
if model in self._registry:
|
||||
raise AlreadyRegistered('The model %s is already registered' % model.__name__)
|
||||
@ -362,7 +363,8 @@ class AdminSite(object):
|
||||
# it cannot import models from other applications at the module level,
|
||||
# and django.contrib.admin.forms eventually imports User.
|
||||
from django.contrib.admin.forms import AdminAuthenticationForm
|
||||
context = dict(self.each_context(request),
|
||||
context = dict(
|
||||
self.each_context(request),
|
||||
title=_('Log in'),
|
||||
app_path=request.get_full_path(),
|
||||
)
|
||||
@ -479,8 +481,7 @@ class AdminSite(object):
|
||||
|
||||
request.current_app = self.name
|
||||
|
||||
return TemplateResponse(request, self.index_template or
|
||||
'admin/index.html', context)
|
||||
return TemplateResponse(request, self.index_template or 'admin/index.html', context)
|
||||
|
||||
def app_index(self, request, app_label, extra_context=None):
|
||||
app_dict = self._build_app_dict(request, app_label)
|
||||
@ -489,7 +490,8 @@ class AdminSite(object):
|
||||
# Sort the models alphabetically within each app.
|
||||
app_dict['models'].sort(key=lambda x: x['name'])
|
||||
app_name = apps.get_app_config(app_label).verbose_name
|
||||
context = dict(self.each_context(request),
|
||||
context = dict(
|
||||
self.each_context(request),
|
||||
title=_('%(app)s administration') % {'app': app_name},
|
||||
app_list=[app_dict],
|
||||
app_label=app_label,
|
||||
|
@ -36,8 +36,8 @@ IGNORED_PARAMS = (
|
||||
|
||||
class ChangeList(object):
|
||||
def __init__(self, request, model, list_display, list_display_links,
|
||||
list_filter, date_hierarchy, search_fields, list_select_related,
|
||||
list_per_page, list_max_show_all, list_editable, model_admin):
|
||||
list_filter, date_hierarchy, search_fields, list_select_related,
|
||||
list_per_page, list_max_show_all, list_editable, model_admin):
|
||||
self.model = model
|
||||
self.opts = model._meta
|
||||
self.lookup_opts = self.opts
|
||||
@ -111,8 +111,7 @@ class ChangeList(object):
|
||||
for list_filter in self.list_filter:
|
||||
if callable(list_filter):
|
||||
# This is simply a custom list filter class.
|
||||
spec = list_filter(request, lookup_params,
|
||||
self.model, self.model_admin)
|
||||
spec = list_filter(request, lookup_params, self.model, self.model_admin)
|
||||
else:
|
||||
field_path = None
|
||||
if isinstance(list_filter, (tuple, list)):
|
||||
@ -126,12 +125,12 @@ class ChangeList(object):
|
||||
if not isinstance(field, models.Field):
|
||||
field_path = field
|
||||
field = get_fields_from_path(self.model, field_path)[-1]
|
||||
spec = field_list_filter_class(field, request, lookup_params,
|
||||
self.model, self.model_admin, field_path=field_path)
|
||||
spec = field_list_filter_class(
|
||||
field, request, lookup_params,
|
||||
self.model, self.model_admin, field_path=field_path
|
||||
)
|
||||
# Check if we need to use distinct()
|
||||
use_distinct = (use_distinct or
|
||||
lookup_needs_distinct(self.lookup_opts,
|
||||
field_path))
|
||||
use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, field_path)
|
||||
if spec and spec.has_output():
|
||||
filter_specs.append(spec)
|
||||
|
||||
@ -144,8 +143,7 @@ class ChangeList(object):
|
||||
try:
|
||||
for key, value in lookup_params.items():
|
||||
lookup_params[key] = prepare_lookup_value(key, value)
|
||||
use_distinct = (use_distinct or
|
||||
lookup_needs_distinct(self.lookup_opts, key))
|
||||
use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, key)
|
||||
return filter_specs, bool(filter_specs), lookup_params, use_distinct
|
||||
except FieldDoesNotExist as e:
|
||||
six.reraise(IncorrectLookupParameters, IncorrectLookupParameters(e), sys.exc_info()[2])
|
||||
@ -345,8 +343,7 @@ class ChangeList(object):
|
||||
qs = qs.order_by(*ordering)
|
||||
|
||||
# Apply search results
|
||||
qs, search_use_distinct = self.model_admin.get_search_results(
|
||||
request, qs, self.query)
|
||||
qs, search_use_distinct = self.model_admin.get_search_results(request, qs, self.query)
|
||||
|
||||
# Remove duplicates from results, if necessary
|
||||
if filters_use_distinct | search_use_distinct:
|
||||
|
@ -106,10 +106,12 @@ class AdminRadioSelect(forms.RadioSelect):
|
||||
|
||||
|
||||
class AdminFileWidget(forms.ClearableFileInput):
|
||||
template_with_initial = ('<p class="file-upload">%s</p>'
|
||||
% forms.ClearableFileInput.template_with_initial)
|
||||
template_with_clear = ('<span class="clearable-file-input">%s</span>'
|
||||
% forms.ClearableFileInput.template_with_clear)
|
||||
template_with_initial = (
|
||||
'<p class="file-upload">%s</p>' % forms.ClearableFileInput.template_with_initial
|
||||
)
|
||||
template_with_clear = (
|
||||
'<span class="clearable-file-input">%s</span>' % forms.ClearableFileInput.template_with_clear
|
||||
)
|
||||
|
||||
|
||||
def url_params_from_lookup_dict(lookups):
|
||||
@ -170,8 +172,10 @@ class ForeignKeyRawIdWidget(forms.TextInput):
|
||||
attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript code looks for this hook.
|
||||
# TODO: "lookup_id_" is hard-coded here. This should instead use
|
||||
# the correct API to determine the ID dynamically.
|
||||
extra.append('<a href="%s%s" class="related-lookup" id="lookup_id_%s" title="%s"></a>' %
|
||||
(related_url, url, name, _('Lookup')))
|
||||
extra.append(
|
||||
'<a href="%s%s" class="related-lookup" id="lookup_id_%s" title="%s"></a>'
|
||||
% (related_url, url, name, _('Lookup'))
|
||||
)
|
||||
output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)] + extra
|
||||
if value:
|
||||
output.append(self.label_for_value(value))
|
||||
|
@ -82,9 +82,11 @@ def parse_rst(text, default_reference_context, thing_being_parsed=None):
|
||||
|
||||
.. default-role::
|
||||
"""
|
||||
parts = docutils.core.publish_parts(source % text,
|
||||
source_path=thing_being_parsed, destination_path=None,
|
||||
writer_name='html', settings_overrides=overrides)
|
||||
parts = docutils.core.publish_parts(
|
||||
source % text,
|
||||
source_path=thing_being_parsed, destination_path=None,
|
||||
writer_name='html', settings_overrides=overrides,
|
||||
)
|
||||
return mark_safe(parts['fragment'])
|
||||
|
||||
#
|
||||
|
@ -82,8 +82,7 @@ def authenticate(**credentials):
|
||||
return user
|
||||
|
||||
# The credentials supplied are invalid to all backends, fire signal
|
||||
user_login_failed.send(sender=__name__,
|
||||
credentials=_clean_credentials(credentials))
|
||||
user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials))
|
||||
|
||||
|
||||
def login(request, user, backend=None):
|
||||
|
@ -183,10 +183,12 @@ class UserAdmin(admin.ModelAdmin):
|
||||
|
||||
request.current_app = self.admin_site.name
|
||||
|
||||
return TemplateResponse(request,
|
||||
return TemplateResponse(
|
||||
request,
|
||||
self.change_user_password_template or
|
||||
'admin/auth/user/change_password.html',
|
||||
context)
|
||||
context,
|
||||
)
|
||||
|
||||
def response_add(self, request, obj, post_url_continue=None):
|
||||
"""
|
||||
|
@ -12,7 +12,9 @@ class AuthConfig(AppConfig):
|
||||
verbose_name = _("Authentication and Authorization")
|
||||
|
||||
def ready(self):
|
||||
post_migrate.connect(create_permissions,
|
||||
dispatch_uid="django.contrib.auth.management.create_permissions")
|
||||
post_migrate.connect(
|
||||
create_permissions,
|
||||
dispatch_uid="django.contrib.auth.management.create_permissions"
|
||||
)
|
||||
checks.register(check_user_model, checks.Tags.models)
|
||||
checks.register(check_models_permissions, checks.Tags.models)
|
||||
|
@ -33,13 +33,13 @@ class ReadOnlyPasswordHashWidget(forms.Widget):
|
||||
hasher = identify_hasher(encoded)
|
||||
except ValueError:
|
||||
summary = mark_safe("<strong>%s</strong>" % ugettext(
|
||||
"Invalid password format or unknown hashing algorithm."))
|
||||
"Invalid password format or unknown hashing algorithm."
|
||||
))
|
||||
else:
|
||||
summary = format_html_join('',
|
||||
"<strong>{}</strong>: {} ",
|
||||
((ugettext(key), value)
|
||||
for key, value in hasher.safe_summary(encoded).items())
|
||||
)
|
||||
summary = format_html_join(
|
||||
'', '<strong>{}</strong>: {} ',
|
||||
((ugettext(key), value) for key, value in hasher.safe_summary(encoded).items())
|
||||
)
|
||||
|
||||
return format_html("<div{}>{}</div>", flatatt(final_attrs), summary)
|
||||
|
||||
@ -68,13 +68,17 @@ class UserCreationForm(forms.ModelForm):
|
||||
error_messages = {
|
||||
'password_mismatch': _("The two password fields didn't match."),
|
||||
}
|
||||
password1 = forms.CharField(label=_("Password"),
|
||||
password1 = forms.CharField(
|
||||
label=_("Password"),
|
||||
strip=False,
|
||||
widget=forms.PasswordInput)
|
||||
password2 = forms.CharField(label=_("Password confirmation"),
|
||||
widget=forms.PasswordInput,
|
||||
)
|
||||
password2 = forms.CharField(
|
||||
label=_("Password confirmation"),
|
||||
widget=forms.PasswordInput,
|
||||
strip=False,
|
||||
help_text=_("Enter the same password as before, for verification."))
|
||||
help_text=_("Enter the same password as before, for verification."),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
@ -105,10 +109,14 @@ class UserCreationForm(forms.ModelForm):
|
||||
|
||||
|
||||
class UserChangeForm(forms.ModelForm):
|
||||
password = ReadOnlyPasswordHashField(label=_("Password"),
|
||||
help_text=_("Raw passwords are not stored, so there is no way to see "
|
||||
"this user's password, but you can change the password "
|
||||
"using <a href=\"../password/\">this form</a>."))
|
||||
password = ReadOnlyPasswordHashField(
|
||||
label=_("Password"),
|
||||
help_text=_(
|
||||
"Raw passwords are not stored, so there is no way to see this "
|
||||
"user's password, but you can change the password using "
|
||||
"<a href=\"../password/\">this form</a>."
|
||||
),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
@ -136,11 +144,17 @@ class AuthenticationForm(forms.Form):
|
||||
max_length=254,
|
||||
widget=forms.TextInput(attrs={'autofocus': ''}),
|
||||
)
|
||||
password = forms.CharField(label=_("Password"), strip=False, widget=forms.PasswordInput)
|
||||
password = forms.CharField(
|
||||
label=_("Password"),
|
||||
strip=False,
|
||||
widget=forms.PasswordInput,
|
||||
)
|
||||
|
||||
error_messages = {
|
||||
'invalid_login': _("Please enter a correct %(username)s and password. "
|
||||
"Note that both fields may be case-sensitive."),
|
||||
'invalid_login': _(
|
||||
"Please enter a correct %(username)s and password. Note that both "
|
||||
"fields may be case-sensitive."
|
||||
),
|
||||
'inactive': _("This account is inactive."),
|
||||
}
|
||||
|
||||
@ -164,8 +178,7 @@ class AuthenticationForm(forms.Form):
|
||||
password = self.cleaned_data.get('password')
|
||||
|
||||
if username and password:
|
||||
self.user_cache = authenticate(username=username,
|
||||
password=password)
|
||||
self.user_cache = authenticate(username=username, password=password)
|
||||
if self.user_cache is None:
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['invalid_login'],
|
||||
@ -263,9 +276,10 @@ class PasswordResetForm(forms.Form):
|
||||
}
|
||||
if extra_email_context is not None:
|
||||
context.update(extra_email_context)
|
||||
self.send_mail(subject_template_name, email_template_name,
|
||||
context, from_email, user.email,
|
||||
html_email_template_name=html_email_template_name)
|
||||
self.send_mail(
|
||||
subject_template_name, email_template_name, context, from_email,
|
||||
user.email, html_email_template_name=html_email_template_name,
|
||||
)
|
||||
|
||||
|
||||
class SetPasswordForm(forms.Form):
|
||||
@ -276,13 +290,17 @@ class SetPasswordForm(forms.Form):
|
||||
error_messages = {
|
||||
'password_mismatch': _("The two password fields didn't match."),
|
||||
}
|
||||
new_password1 = forms.CharField(label=_("New password"),
|
||||
widget=forms.PasswordInput,
|
||||
strip=False,
|
||||
help_text=password_validation.password_validators_help_text_html())
|
||||
new_password2 = forms.CharField(label=_("New password confirmation"),
|
||||
strip=False,
|
||||
widget=forms.PasswordInput)
|
||||
new_password1 = forms.CharField(
|
||||
label=_("New password"),
|
||||
widget=forms.PasswordInput,
|
||||
strip=False,
|
||||
help_text=password_validation.password_validators_help_text_html(),
|
||||
)
|
||||
new_password2 = forms.CharField(
|
||||
label=_("New password confirmation"),
|
||||
strip=False,
|
||||
widget=forms.PasswordInput,
|
||||
)
|
||||
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
self.user = user
|
||||
@ -314,8 +332,7 @@ class PasswordChangeForm(SetPasswordForm):
|
||||
password.
|
||||
"""
|
||||
error_messages = dict(SetPasswordForm.error_messages, **{
|
||||
'password_incorrect': _("Your old password was entered incorrectly. "
|
||||
"Please enter it again."),
|
||||
'password_incorrect': _("Your old password was entered incorrectly. Please enter it again."),
|
||||
})
|
||||
old_password = forms.CharField(
|
||||
label=_("Old password"),
|
||||
|
@ -30,8 +30,10 @@ def _get_builtin_permissions(opts):
|
||||
"""
|
||||
perms = []
|
||||
for action in opts.default_permissions:
|
||||
perms.append((get_permission_codename(action, opts),
|
||||
'Can %s %s' % (action, opts.verbose_name_raw)))
|
||||
perms.append((
|
||||
get_permission_codename(action, opts),
|
||||
'Can %s %s' % (action, opts.verbose_name_raw)
|
||||
))
|
||||
return perms
|
||||
|
||||
|
||||
@ -125,9 +127,11 @@ def get_default_username(check_db=True):
|
||||
|
||||
default_username = get_system_username()
|
||||
try:
|
||||
default_username = (unicodedata.normalize('NFKD', default_username)
|
||||
.encode('ascii', 'ignore').decode('ascii')
|
||||
.replace(' ', '').lower())
|
||||
default_username = (
|
||||
unicodedata.normalize('NFKD', default_username)
|
||||
.encode('ascii', 'ignore').decode('ascii')
|
||||
.replace(' ', '').lower()
|
||||
)
|
||||
except UnicodeDecodeError:
|
||||
return ''
|
||||
|
||||
|
@ -22,11 +22,15 @@ class Command(BaseCommand):
|
||||
return p
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('username', nargs='?',
|
||||
help='Username to change password for; by default, it\'s the current username.')
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
parser.add_argument(
|
||||
'username', nargs='?',
|
||||
help='Username to change password for; by default, it\'s the current username.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Specifies the database to use. Default is "default".')
|
||||
help='Specifies the database to use. Default is "default".',
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if options['username']:
|
||||
|
@ -31,22 +31,32 @@ class Command(BaseCommand):
|
||||
self.username_field = self.UserModel._meta.get_field(self.UserModel.USERNAME_FIELD)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--%s' % self.UserModel.USERNAME_FIELD,
|
||||
parser.add_argument(
|
||||
'--%s' % self.UserModel.USERNAME_FIELD,
|
||||
dest=self.UserModel.USERNAME_FIELD, default=None,
|
||||
help='Specifies the login for the superuser.')
|
||||
parser.add_argument('--noinput', '--no-input',
|
||||
help='Specifies the login for the superuser.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--noinput', '--no-input',
|
||||
action='store_false', dest='interactive', default=True,
|
||||
help=('Tells Django to NOT prompt the user for input of any kind. '
|
||||
'You must use --%s with --noinput, along with an option for '
|
||||
'any other required field. Superusers created with --noinput will '
|
||||
' not be able to log in until they\'re given a valid password.' %
|
||||
self.UserModel.USERNAME_FIELD))
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Specifies the database to use. Default is "default".')
|
||||
help=(
|
||||
'Tells Django to NOT prompt the user for input of any kind. '
|
||||
'You must use --%s with --noinput, along with an option for '
|
||||
'any other required field. Superusers created with --noinput will '
|
||||
'not be able to log in until they\'re given a valid password.' %
|
||||
self.UserModel.USERNAME_FIELD
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Specifies the database to use. Default is "default".',
|
||||
)
|
||||
for field in self.UserModel.REQUIRED_FIELDS:
|
||||
parser.add_argument('--%s' % field, dest=field, default=None,
|
||||
help='Specifies the %s for the superuser.' % field)
|
||||
parser.add_argument(
|
||||
'--%s' % field, dest=field, default=None,
|
||||
help='Specifies the %s for the superuser.' % field,
|
||||
)
|
||||
|
||||
def execute(self, *args, **options):
|
||||
self.stdin = options.get('stdin', sys.stdin) # Used for testing
|
||||
@ -67,8 +77,7 @@ class Command(BaseCommand):
|
||||
if not options['interactive']:
|
||||
try:
|
||||
if not username:
|
||||
raise CommandError("You must use --%s with --noinput." %
|
||||
self.UserModel.USERNAME_FIELD)
|
||||
raise CommandError("You must use --%s with --noinput." % self.UserModel.USERNAME_FIELD)
|
||||
username = self.username_field.clean(username, None)
|
||||
|
||||
for field_name in self.UserModel.REQUIRED_FIELDS:
|
||||
|
@ -15,10 +15,10 @@ def check_generic_foreign_keys(app_configs=None, **kwargs):
|
||||
else:
|
||||
models = chain.from_iterable(app_config.get_models() for app_config in app_configs)
|
||||
errors = []
|
||||
fields = (obj
|
||||
for model in models
|
||||
for obj in six.itervalues(vars(model))
|
||||
if isinstance(obj, GenericForeignKey))
|
||||
fields = (
|
||||
obj for model in models for obj in six.itervalues(vars(model))
|
||||
if isinstance(obj, GenericForeignKey)
|
||||
)
|
||||
for field in fields:
|
||||
errors.extend(field.check())
|
||||
return errors
|
||||
|
@ -299,7 +299,7 @@ class GenericRelation(ForeignObject):
|
||||
rel_class = GenericRel
|
||||
|
||||
def __init__(self, to, object_id_field='object_id', content_type_field='content_type',
|
||||
for_concrete_model=True, related_query_name=None, limit_choices_to=None, **kwargs):
|
||||
for_concrete_model=True, related_query_name=None, limit_choices_to=None, **kwargs):
|
||||
kwargs['rel'] = self.rel_class(
|
||||
self, to,
|
||||
related_query_name=related_query_name,
|
||||
|
@ -38,16 +38,11 @@ class BaseGenericInlineFormSet(BaseModelFormSet):
|
||||
@classmethod
|
||||
def get_default_prefix(cls):
|
||||
opts = cls.model._meta
|
||||
return '-'.join(
|
||||
(opts.app_label, opts.model_name,
|
||||
cls.ct_field.name, cls.ct_fk_field.name)
|
||||
)
|
||||
return '-'.join((opts.app_label, opts.model_name, cls.ct_field.name, cls.ct_fk_field.name))
|
||||
|
||||
def save_new(self, form, commit=True):
|
||||
setattr(form.instance, self.ct_field.get_attname(),
|
||||
ContentType.objects.get_for_model(self.instance).pk)
|
||||
setattr(form.instance, self.ct_fk_field.get_attname(),
|
||||
self.instance.pk)
|
||||
setattr(form.instance, self.ct_field.get_attname(), ContentType.objects.get_for_model(self.instance).pk)
|
||||
setattr(form.instance, self.ct_fk_field.get_attname(), self.instance.pk)
|
||||
return form.save(commit=commit)
|
||||
|
||||
|
||||
@ -76,13 +71,12 @@ def generic_inlineformset_factory(model, form=ModelForm,
|
||||
exclude.extend([ct_field.name, fk_field.name])
|
||||
else:
|
||||
exclude = [ct_field.name, fk_field.name]
|
||||
FormSet = modelformset_factory(model, form=form,
|
||||
formfield_callback=formfield_callback,
|
||||
formset=formset,
|
||||
extra=extra, can_delete=can_delete, can_order=can_order,
|
||||
fields=fields, exclude=exclude, max_num=max_num,
|
||||
validate_max=validate_max, min_num=min_num,
|
||||
validate_min=validate_min)
|
||||
FormSet = modelformset_factory(
|
||||
model, form=form, formfield_callback=formfield_callback,
|
||||
formset=formset, extra=extra, can_delete=can_delete,
|
||||
can_order=can_order, fields=fields, exclude=exclude, max_num=max_num,
|
||||
validate_max=validate_max, min_num=min_num, validate_min=validate_min,
|
||||
)
|
||||
FormSet.ct_field = ct_field
|
||||
FormSet.ct_fk_field = fk_field
|
||||
FormSet.for_concrete_model = for_concrete_model
|
||||
|
@ -22,9 +22,11 @@ class FlatPage(models.Model):
|
||||
"the system will use 'flatpages/default.html'."
|
||||
),
|
||||
)
|
||||
registration_required = models.BooleanField(_('registration required'),
|
||||
registration_required = models.BooleanField(
|
||||
_('registration required'),
|
||||
help_text=_("If this is checked, only logged-in users will be able to view the page."),
|
||||
default=False)
|
||||
default=False,
|
||||
)
|
||||
sites = models.ManyToManyField(Site, verbose_name=_('sites'))
|
||||
|
||||
class Meta:
|
||||
|
@ -34,13 +34,11 @@ def flatpage(request, url):
|
||||
url = '/' + url
|
||||
site_id = get_current_site(request).id
|
||||
try:
|
||||
f = get_object_or_404(FlatPage,
|
||||
url=url, sites=site_id)
|
||||
f = get_object_or_404(FlatPage, url=url, sites=site_id)
|
||||
except Http404:
|
||||
if not url.endswith('/') and settings.APPEND_SLASH:
|
||||
url += '/'
|
||||
f = get_object_or_404(FlatPage,
|
||||
url=url, sites=site_id)
|
||||
f = get_object_or_404(FlatPage, url=url, sites=site_id)
|
||||
return HttpResponsePermanentRedirect('%s/' % request.path)
|
||||
else:
|
||||
raise
|
||||
|
@ -26,8 +26,7 @@ elif os.name == 'nt':
|
||||
lib_names = ['gdal111', 'gdal110', 'gdal19', 'gdal18', 'gdal17']
|
||||
elif os.name == 'posix':
|
||||
# *NIX library names.
|
||||
lib_names = ['gdal', 'GDAL', 'gdal1.11.0', 'gdal1.10.0', 'gdal1.9.0',
|
||||
'gdal1.8.0', 'gdal1.7.0']
|
||||
lib_names = ['gdal', 'GDAL', 'gdal1.11.0', 'gdal1.10.0', 'gdal1.9.0', 'gdal1.8.0', 'gdal1.7.0']
|
||||
else:
|
||||
raise GDALException('Unsupported OS "%s"' % os.name)
|
||||
|
||||
@ -40,9 +39,10 @@ if lib_names:
|
||||
break
|
||||
|
||||
if lib_path is None:
|
||||
raise GDALException('Could not find the GDAL library (tried "%s"). '
|
||||
'Try setting GDAL_LIBRARY_PATH in your settings.' %
|
||||
'", "'.join(lib_names))
|
||||
raise GDALException(
|
||||
'Could not find the GDAL library (tried "%s"). Try setting '
|
||||
'GDAL_LIBRARY_PATH in your settings.' % '", "'.join(lib_names)
|
||||
)
|
||||
|
||||
# This loads the GDAL/OGR C library
|
||||
lgdal = CDLL(lib_path)
|
||||
|
@ -42,7 +42,8 @@ reset_reading = void_output(lgdal.OGR_L_ResetReading, [c_void_p], errcheck=False
|
||||
test_capability = int_output(lgdal.OGR_L_TestCapability, [c_void_p, c_char_p])
|
||||
get_spatial_filter = geom_output(lgdal.OGR_L_GetSpatialFilter, [c_void_p])
|
||||
set_spatial_filter = void_output(lgdal.OGR_L_SetSpatialFilter, [c_void_p, c_void_p], errcheck=False)
|
||||
set_spatial_filter_rect = void_output(lgdal.OGR_L_SetSpatialFilterRect,
|
||||
set_spatial_filter_rect = void_output(
|
||||
lgdal.OGR_L_SetSpatialFilterRect,
|
||||
[c_void_p, c_double, c_double, c_double, c_double], errcheck=False
|
||||
)
|
||||
|
||||
@ -61,7 +62,8 @@ get_feat_geom_ref = geom_output(lgdal.OGR_F_GetGeometryRef, [c_void_p])
|
||||
get_feat_field_count = int_output(lgdal.OGR_F_GetFieldCount, [c_void_p])
|
||||
get_feat_field_defn = voidptr_output(lgdal.OGR_F_GetFieldDefnRef, [c_void_p, c_int])
|
||||
get_fid = int_output(lgdal.OGR_F_GetFID, [c_void_p])
|
||||
get_field_as_datetime = int_output(lgdal.OGR_F_GetFieldAsDateTime,
|
||||
get_field_as_datetime = int_output(
|
||||
lgdal.OGR_F_GetFieldAsDateTime,
|
||||
[c_void_p, c_int, c_int_p, c_int_p, c_int_p, c_int_p, c_int_p, c_int_p]
|
||||
)
|
||||
get_field_as_double = double_output(lgdal.OGR_F_GetFieldAsDouble, [c_void_p, c_int])
|
||||
|
@ -112,8 +112,7 @@ def string_output(func, argtypes, offset=-1, str_result=False, decoding=None):
|
||||
# Dynamically defining our error-checking function with the
|
||||
# given offset.
|
||||
def _check_str(result, func, cargs):
|
||||
res = check_string(result, func, cargs,
|
||||
offset=offset, str_result=str_result)
|
||||
res = check_string(result, func, cargs, offset=offset, str_result=str_result)
|
||||
if res and decoding:
|
||||
res = res.decode(decoding)
|
||||
return res
|
||||
|
@ -82,7 +82,8 @@ get_geom_count = int_output(lgdal.OGR_G_GetGeometryCount, [c_void_p])
|
||||
get_geom_name = const_string_output(lgdal.OGR_G_GetGeometryName, [c_void_p], decoding='ascii')
|
||||
get_geom_type = int_output(lgdal.OGR_G_GetGeometryType, [c_void_p])
|
||||
get_point_count = int_output(lgdal.OGR_G_GetPointCount, [c_void_p])
|
||||
get_point = void_output(lgdal.OGR_G_GetPoint,
|
||||
get_point = void_output(
|
||||
lgdal.OGR_G_GetPoint,
|
||||
[c_void_p, c_int, POINTER(c_double), POINTER(c_double), POINTER(c_double)], errcheck=False
|
||||
)
|
||||
geom_close_rings = void_output(lgdal.OGR_G_CloseRings, [c_void_p], errcheck=False)
|
||||
|
@ -35,7 +35,8 @@ if GDAL_VERSION >= (2, 0):
|
||||
else:
|
||||
close_ds = void_output(std_call('GDALClose'), [c_void_p])
|
||||
flush_ds = int_output(std_call('GDALFlushCache'), [c_void_p])
|
||||
copy_ds = voidptr_output(std_call('GDALCreateCopy'),
|
||||
copy_ds = voidptr_output(
|
||||
std_call('GDALCreateCopy'),
|
||||
[c_void_p, c_char_p, c_void_p, c_int, POINTER(c_char_p), c_void_p, c_void_p]
|
||||
)
|
||||
add_band_ds = void_output(std_call('GDALAddBand'), [c_void_p, c_int])
|
||||
@ -51,7 +52,8 @@ get_ds_geotransform = void_output(std_call('GDALGetGeoTransform'), [c_void_p, PO
|
||||
set_ds_geotransform = void_output(std_call('GDALSetGeoTransform'), [c_void_p, POINTER(c_double * 6)])
|
||||
|
||||
# Raster Band Routines
|
||||
band_io = void_output(std_call('GDALRasterIO'),
|
||||
band_io = void_output(
|
||||
std_call('GDALRasterIO'),
|
||||
[c_void_p, c_int, c_int, c_int, c_int, c_int, c_void_p, c_int, c_int, c_int, c_int, c_int]
|
||||
)
|
||||
get_band_xsize = int_output(std_call('GDALGetRasterBandXSize'), [c_void_p])
|
||||
@ -74,15 +76,18 @@ get_band_statistics = void_output(
|
||||
],
|
||||
errcheck=False
|
||||
)
|
||||
compute_band_statistics = void_output(std_call('GDALComputeRasterStatistics'),
|
||||
compute_band_statistics = void_output(
|
||||
std_call('GDALComputeRasterStatistics'),
|
||||
[c_void_p, c_int, POINTER(c_double), POINTER(c_double), POINTER(c_double), POINTER(c_double), c_void_p, c_void_p],
|
||||
errcheck=False
|
||||
)
|
||||
|
||||
# Reprojection routine
|
||||
reproject_image = void_output(std_call('GDALReprojectImage'),
|
||||
reproject_image = void_output(
|
||||
std_call('GDALReprojectImage'),
|
||||
[c_void_p, c_char_p, c_void_p, c_char_p, c_int, c_double, c_double, c_void_p, c_void_p, c_void_p]
|
||||
)
|
||||
auto_create_warped_vrt = voidptr_output(std_call('GDALAutoCreateWarpedVRT'),
|
||||
auto_create_warped_vrt = voidptr_output(
|
||||
std_call('GDALAutoCreateWarpedVRT'),
|
||||
[c_void_p, c_char_p, c_char_p, c_int, c_double, c_void_p]
|
||||
)
|
||||
|
@ -56,7 +56,8 @@ angular_units = units_func(lgdal.OSRGetAngularUnits)
|
||||
# For exporting to WKT, PROJ.4, "Pretty" WKT, and XML.
|
||||
to_wkt = string_output(std_call('OSRExportToWkt'), [c_void_p, POINTER(c_char_p)], decoding='ascii')
|
||||
to_proj = string_output(std_call('OSRExportToProj4'), [c_void_p, POINTER(c_char_p)], decoding='ascii')
|
||||
to_pretty_wkt = string_output(std_call('OSRExportToPrettyWkt'),
|
||||
to_pretty_wkt = string_output(
|
||||
std_call('OSRExportToPrettyWkt'),
|
||||
[c_void_p, POINTER(c_char_p), c_int], offset=-2, decoding='ascii'
|
||||
)
|
||||
|
||||
|
@ -176,6 +176,8 @@ class Polygon(GEOSGeometry):
|
||||
@property
|
||||
def kml(self):
|
||||
"Returns the KML representation of this Polygon."
|
||||
inner_kml = ''.join("<innerBoundaryIs>%s</innerBoundaryIs>" % self[i + 1].kml
|
||||
for i in range(self.num_interior_rings))
|
||||
inner_kml = ''.join(
|
||||
"<innerBoundaryIs>%s</innerBoundaryIs>" % self[i + 1].kml
|
||||
for i in range(self.num_interior_rings)
|
||||
)
|
||||
return "<Polygon><outerBoundaryIs>%s</outerBoundaryIs>%s</Polygon>" % (self[0].kml, inner_kml)
|
||||
|
@ -31,49 +31,70 @@ class ListOptionAction(argparse.Action):
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ('Inspects the given OGR-compatible data source (e.g., a shapefile) and outputs\n'
|
||||
'a GeoDjango model with the given model name. For example:\n'
|
||||
' ./manage.py ogrinspect zipcode.shp Zipcode')
|
||||
help = (
|
||||
'Inspects the given OGR-compatible data source (e.g., a shapefile) and outputs\n'
|
||||
'a GeoDjango model with the given model name. For example:\n'
|
||||
' ./manage.py ogrinspect zipcode.shp Zipcode'
|
||||
)
|
||||
|
||||
requires_system_checks = False
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('data_source', help='Path to the data source.')
|
||||
parser.add_argument('model_name', help='Name of the model to create.')
|
||||
parser.add_argument('--blank', dest='blank',
|
||||
parser.add_argument(
|
||||
'--blank', dest='blank',
|
||||
action=ListOptionAction, default=False,
|
||||
help='Use a comma separated list of OGR field names to add '
|
||||
'the `blank=True` option to the field definition. Set to `true` '
|
||||
'to apply to all applicable fields.')
|
||||
parser.add_argument('--decimal', dest='decimal',
|
||||
'the `blank=True` option to the field definition. Set to `true` '
|
||||
'to apply to all applicable fields.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--decimal', dest='decimal',
|
||||
action=ListOptionAction, default=False,
|
||||
help='Use a comma separated list of OGR float fields to '
|
||||
'generate `DecimalField` instead of the default '
|
||||
'`FloatField`. Set to `true` to apply to all OGR float fields.')
|
||||
parser.add_argument('--geom-name', dest='geom_name', default='geom',
|
||||
help='Specifies the model name for the Geometry Field '
|
||||
'(defaults to `geom`)')
|
||||
parser.add_argument('--layer', dest='layer_key',
|
||||
'generate `DecimalField` instead of the default '
|
||||
'`FloatField`. Set to `true` to apply to all OGR float fields.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--geom-name', dest='geom_name', default='geom',
|
||||
help='Specifies the model name for the Geometry Field (defaults to `geom`)'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--layer', dest='layer_key',
|
||||
action=LayerOptionAction, default=0,
|
||||
help='The key for specifying which layer in the OGR data '
|
||||
'source to use. Defaults to 0 (the first layer). May be '
|
||||
'an integer or a string identifier for the layer.')
|
||||
parser.add_argument('--multi-geom', action='store_true',
|
||||
'source to use. Defaults to 0 (the first layer). May be '
|
||||
'an integer or a string identifier for the layer.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--multi-geom', action='store_true',
|
||||
dest='multi_geom', default=False,
|
||||
help='Treat the geometry in the data source as a geometry collection.')
|
||||
parser.add_argument('--name-field', dest='name_field',
|
||||
help='Specifies a field name to return for the `__unicode__`/`__str__` function.')
|
||||
parser.add_argument('--no-imports', action='store_false', dest='imports', default=True,
|
||||
help='Do not include `from django.contrib.gis.db import models` statement.')
|
||||
parser.add_argument('--null', dest='null', action=ListOptionAction, default=False,
|
||||
help='Treat the geometry in the data source as a geometry collection.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--name-field', dest='name_field',
|
||||
help='Specifies a field name to return for the `__unicode__`/`__str__` function.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-imports', action='store_false', dest='imports', default=True,
|
||||
help='Do not include `from django.contrib.gis.db import models` statement.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--null', dest='null', action=ListOptionAction, default=False,
|
||||
help='Use a comma separated list of OGR field names to add '
|
||||
'the `null=True` option to the field definition. Set to `true` '
|
||||
'to apply to all applicable fields.')
|
||||
parser.add_argument('--srid', dest='srid',
|
||||
'the `null=True` option to the field definition. Set to `true` '
|
||||
'to apply to all applicable fields.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--srid', dest='srid',
|
||||
help='The SRID to use for the Geometry Field. If it can be '
|
||||
'determined, the SRID of the data source is used.')
|
||||
parser.add_argument('--mapping', action='store_true', dest='mapping',
|
||||
help='Generate mapping dictionary for use with `LayerMapping`.')
|
||||
'determined, the SRID of the data source is used.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--mapping', action='store_true', dest='mapping',
|
||||
help='Generate mapping dictionary for use with `LayerMapping`.',
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
data_source, model_name = options.pop('data_source'), options.pop('model_name')
|
||||
@ -97,10 +118,11 @@ class Command(BaseCommand):
|
||||
if options['mapping']:
|
||||
# Constructing the keyword arguments for `mapping`, and
|
||||
# calling it on the data source.
|
||||
kwargs = {'geom_name': options['geom_name'],
|
||||
'layer_key': options['layer_key'],
|
||||
'multi_geom': options['multi_geom'],
|
||||
}
|
||||
kwargs = {
|
||||
'geom_name': options['geom_name'],
|
||||
'layer_key': options['layer_key'],
|
||||
'multi_geom': options['multi_geom'],
|
||||
}
|
||||
mapping_dict = mapping(ds, **kwargs)
|
||||
# This extra legwork is so that the dictionary definition comes
|
||||
# out in the same order as the fields in the model definition.
|
||||
|
@ -78,8 +78,7 @@ class MeasureBase(object):
|
||||
raise AttributeError('Unknown unit type: %s' % name)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s=%s)' % (pretty_name(self), self._default_unit,
|
||||
getattr(self, self._default_unit))
|
||||
return '%s(%s=%s)' % (pretty_name(self), self._default_unit, getattr(self, self._default_unit))
|
||||
|
||||
def __str__(self):
|
||||
return '%s %s' % (getattr(self, self._default_unit), self._default_unit)
|
||||
@ -102,8 +101,10 @@ class MeasureBase(object):
|
||||
|
||||
def __add__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.__class__(default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard + other.standard)})
|
||||
return self.__class__(
|
||||
default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard + other.standard)}
|
||||
)
|
||||
else:
|
||||
raise TypeError('%(class)s must be added with %(class)s' % {"class": pretty_name(self)})
|
||||
|
||||
@ -116,8 +117,10 @@ class MeasureBase(object):
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.__class__(default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard - other.standard)})
|
||||
return self.__class__(
|
||||
default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard - other.standard)}
|
||||
)
|
||||
else:
|
||||
raise TypeError('%(class)s must be subtracted from %(class)s' % {"class": pretty_name(self)})
|
||||
|
||||
@ -130,8 +133,10 @@ class MeasureBase(object):
|
||||
|
||||
def __mul__(self, other):
|
||||
if isinstance(other, NUMERIC_TYPES):
|
||||
return self.__class__(default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard * other)})
|
||||
return self.__class__(
|
||||
default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard * other)}
|
||||
)
|
||||
else:
|
||||
raise TypeError('%(class)s must be multiplied with number' % {"class": pretty_name(self)})
|
||||
|
||||
@ -149,8 +154,10 @@ class MeasureBase(object):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.standard / other.standard
|
||||
if isinstance(other, NUMERIC_TYPES):
|
||||
return self.__class__(default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard / other)})
|
||||
return self.__class__(
|
||||
default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard / other)}
|
||||
)
|
||||
else:
|
||||
raise TypeError('%(class)s must be divided with number or %(class)s' % {"class": pretty_name(self)})
|
||||
|
||||
@ -300,11 +307,15 @@ class Distance(MeasureBase):
|
||||
|
||||
def __mul__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return Area(default_unit=AREA_PREFIX + self._default_unit,
|
||||
**{AREA_PREFIX + self.STANDARD_UNIT: (self.standard * other.standard)})
|
||||
return Area(
|
||||
default_unit=AREA_PREFIX + self._default_unit,
|
||||
**{AREA_PREFIX + self.STANDARD_UNIT: (self.standard * other.standard)}
|
||||
)
|
||||
elif isinstance(other, NUMERIC_TYPES):
|
||||
return self.__class__(default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard * other)})
|
||||
return self.__class__(
|
||||
default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard * other)}
|
||||
)
|
||||
else:
|
||||
raise TypeError('%(distance)s must be multiplied with number or %(distance)s' % {
|
||||
"distance": pretty_name(self.__class__),
|
||||
@ -320,8 +331,10 @@ class Area(MeasureBase):
|
||||
|
||||
def __truediv__(self, other):
|
||||
if isinstance(other, NUMERIC_TYPES):
|
||||
return self.__class__(default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard / other)})
|
||||
return self.__class__(
|
||||
default_unit=self._default_unit,
|
||||
**{self.STANDARD_UNIT: (self.standard / other)}
|
||||
)
|
||||
else:
|
||||
raise TypeError('%(class)s must be divided by a number' % {"class": pretty_name(self)})
|
||||
|
||||
|
@ -24,8 +24,10 @@ def compress_kml(kml):
|
||||
|
||||
def render_to_kml(*args, **kwargs):
|
||||
"Renders the response as KML (using the correct MIME type)."
|
||||
return HttpResponse(loader.render_to_string(*args, **kwargs),
|
||||
content_type='application/vnd.google-earth.kml+xml')
|
||||
return HttpResponse(
|
||||
loader.render_to_string(*args, **kwargs),
|
||||
content_type='application/vnd.google-earth.kml+xml',
|
||||
)
|
||||
|
||||
|
||||
def render_to_kmz(*args, **kwargs):
|
||||
@ -33,11 +35,12 @@ def render_to_kmz(*args, **kwargs):
|
||||
Compresses the KML content and returns as KMZ (using the correct
|
||||
MIME type).
|
||||
"""
|
||||
return HttpResponse(compress_kml(loader.render_to_string(*args, **kwargs)),
|
||||
content_type='application/vnd.google-earth.kmz')
|
||||
return HttpResponse(
|
||||
compress_kml(loader.render_to_string(*args, **kwargs)),
|
||||
content_type='application/vnd.google-earth.kmz',
|
||||
)
|
||||
|
||||
|
||||
def render_to_text(*args, **kwargs):
|
||||
"Renders the response using the MIME type for plain text."
|
||||
return HttpResponse(loader.render_to_string(*args, **kwargs),
|
||||
content_type='text/plain')
|
||||
return HttpResponse(loader.render_to_string(*args, **kwargs), content_type='text/plain')
|
||||
|
@ -24,8 +24,10 @@ def add_message(request, level, message, extra_tags='', fail_silently=False):
|
||||
if hasattr(request, '_messages'):
|
||||
return request._messages.add(level, message, extra_tags)
|
||||
if not fail_silently:
|
||||
raise MessageFailure('You cannot add messages without installing '
|
||||
'django.contrib.messages.middleware.MessageMiddleware')
|
||||
raise MessageFailure(
|
||||
'You cannot add messages without installing '
|
||||
'django.contrib.messages.middleware.MessageMiddleware'
|
||||
)
|
||||
|
||||
|
||||
def get_messages(request):
|
||||
|
@ -82,13 +82,14 @@ class CookieStorage(BaseStorage):
|
||||
store, or deletes the cookie.
|
||||
"""
|
||||
if encoded_data:
|
||||
response.set_cookie(self.cookie_name, encoded_data,
|
||||
response.set_cookie(
|
||||
self.cookie_name, encoded_data,
|
||||
domain=settings.SESSION_COOKIE_DOMAIN,
|
||||
secure=settings.SESSION_COOKIE_SECURE or None,
|
||||
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
|
||||
httponly=settings.SESSION_COOKIE_HTTPONLY or None,
|
||||
)
|
||||
else:
|
||||
response.delete_cookie(self.cookie_name,
|
||||
domain=settings.SESSION_COOKIE_DOMAIN)
|
||||
response.delete_cookie(self.cookie_name, domain=settings.SESSION_COOKIE_DOMAIN)
|
||||
|
||||
def _store(self, messages, response, remove_oldest=True, *args, **kwargs):
|
||||
"""
|
||||
|
@ -44,14 +44,16 @@ class KeysValidator(object):
|
||||
keys = set(value.keys())
|
||||
missing_keys = self.keys - keys
|
||||
if missing_keys:
|
||||
raise ValidationError(self.messages['missing_keys'],
|
||||
raise ValidationError(
|
||||
self.messages['missing_keys'],
|
||||
code='missing_keys',
|
||||
params={'keys': ', '.join(missing_keys)},
|
||||
)
|
||||
if self.strict:
|
||||
extra_keys = keys - self.keys
|
||||
if extra_keys:
|
||||
raise ValidationError(self.messages['extra_keys'],
|
||||
raise ValidationError(
|
||||
self.messages['extra_keys'],
|
||||
code='extra_keys',
|
||||
params={'keys': ', '.join(extra_keys)},
|
||||
)
|
||||
|
@ -7,10 +7,18 @@ from django.utils.translation import ugettext_lazy as _
|
||||
@python_2_unicode_compatible
|
||||
class Redirect(models.Model):
|
||||
site = models.ForeignKey(Site, models.CASCADE, verbose_name=_('site'))
|
||||
old_path = models.CharField(_('redirect from'), max_length=200, db_index=True,
|
||||
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."))
|
||||
new_path = models.CharField(_('redirect to'), max_length=200, blank=True,
|
||||
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."))
|
||||
old_path = models.CharField(
|
||||
_('redirect from'),
|
||||
max_length=200,
|
||||
db_index=True,
|
||||
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."),
|
||||
)
|
||||
new_path = models.CharField(
|
||||
_('redirect to'),
|
||||
max_length=200,
|
||||
blank=True,
|
||||
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('redirect')
|
||||
|
@ -110,8 +110,7 @@ class SessionBase(object):
|
||||
# ValueError, SuspiciousOperation, unpickling exceptions. If any of
|
||||
# these happen, just return an empty dictionary (an empty session).
|
||||
if isinstance(e, SuspiciousOperation):
|
||||
logger = logging.getLogger('django.security.%s' %
|
||||
e.__class__.__name__)
|
||||
logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
|
||||
logger.warning(force_text(e))
|
||||
return {}
|
||||
|
||||
|
@ -45,12 +45,10 @@ class SessionStore(DBStore):
|
||||
expire_date__gt=timezone.now()
|
||||
)
|
||||
data = self.decode(s.session_data)
|
||||
self._cache.set(self.cache_key, data,
|
||||
self.get_expiry_age(expiry=s.expire_date))
|
||||
self._cache.set(self.cache_key, data, self.get_expiry_age(expiry=s.expire_date))
|
||||
except (self.model.DoesNotExist, SuspiciousOperation) as e:
|
||||
if isinstance(e, SuspiciousOperation):
|
||||
logger = logging.getLogger('django.security.%s' %
|
||||
e.__class__.__name__)
|
||||
logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
|
||||
logger.warning(force_text(e))
|
||||
self._session_key = None
|
||||
data = {}
|
||||
|
@ -37,8 +37,7 @@ class SessionStore(SessionBase):
|
||||
return self.decode(s.session_data)
|
||||
except (self.model.DoesNotExist, SuspiciousOperation) as e:
|
||||
if isinstance(e, SuspiciousOperation):
|
||||
logger = logging.getLogger('django.security.%s' %
|
||||
e.__class__.__name__)
|
||||
logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
|
||||
logger.warning(force_text(e))
|
||||
self._session_key = None
|
||||
return {}
|
||||
|
@ -92,8 +92,7 @@ class SessionStore(SessionBase):
|
||||
session_data = self.decode(file_data)
|
||||
except (EOFError, SuspiciousOperation) as e:
|
||||
if isinstance(e, SuspiciousOperation):
|
||||
logger = logging.getLogger('django.security.%s' %
|
||||
e.__class__.__name__)
|
||||
logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
|
||||
logger.warning(force_text(e))
|
||||
self.create()
|
||||
|
||||
@ -160,8 +159,7 @@ class SessionStore(SessionBase):
|
||||
dir, prefix = os.path.split(session_file_name)
|
||||
|
||||
try:
|
||||
output_file_fd, output_file_name = tempfile.mkstemp(dir=dir,
|
||||
prefix=prefix + '_out_')
|
||||
output_file_fd, output_file_name = tempfile.mkstemp(dir=dir, prefix=prefix + '_out_')
|
||||
renamed = False
|
||||
try:
|
||||
try:
|
||||
|
@ -12,11 +12,13 @@ class SessionStore(SessionBase):
|
||||
raises BadSignature if signature fails.
|
||||
"""
|
||||
try:
|
||||
return signing.loads(self.session_key,
|
||||
return signing.loads(
|
||||
self.session_key,
|
||||
serializer=self.serializer,
|
||||
# This doesn't handle non-default expiry dates, see #19201
|
||||
max_age=settings.SESSION_COOKIE_AGE,
|
||||
salt='django.contrib.sessions.backends.signed_cookies')
|
||||
salt='django.contrib.sessions.backends.signed_cookies',
|
||||
)
|
||||
except Exception:
|
||||
# BadSignature, ValueError, or unpickling exceptions. If any of
|
||||
# these happen, reset the session.
|
||||
@ -73,9 +75,11 @@ class SessionStore(SessionBase):
|
||||
session key.
|
||||
"""
|
||||
session_cache = getattr(self, '_session_cache', {})
|
||||
return signing.dumps(session_cache, compress=True,
|
||||
return signing.dumps(
|
||||
session_cache, compress=True,
|
||||
salt='django.contrib.sessions.backends.signed_cookies',
|
||||
serializer=self.serializer)
|
||||
serializer=self.serializer,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def clear_expired(cls):
|
||||
|
@ -33,8 +33,7 @@ class SessionMiddleware(object):
|
||||
# First check if we need to delete this cookie.
|
||||
# The session should be deleted only if the session is entirely empty
|
||||
if settings.SESSION_COOKIE_NAME in request.COOKIES and empty:
|
||||
response.delete_cookie(settings.SESSION_COOKIE_NAME,
|
||||
domain=settings.SESSION_COOKIE_DOMAIN)
|
||||
response.delete_cookie(settings.SESSION_COOKIE_NAME, domain=settings.SESSION_COOKIE_DOMAIN)
|
||||
else:
|
||||
if accessed:
|
||||
patch_vary_headers(response, ('Cookie',))
|
||||
@ -56,10 +55,12 @@ class SessionMiddleware(object):
|
||||
# page will result in a redirect to the login page
|
||||
# if required.
|
||||
return redirect(request.path)
|
||||
response.set_cookie(settings.SESSION_COOKIE_NAME,
|
||||
request.session.session_key, max_age=max_age,
|
||||
expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
|
||||
path=settings.SESSION_COOKIE_PATH,
|
||||
secure=settings.SESSION_COOKIE_SECURE or None,
|
||||
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
|
||||
response.set_cookie(
|
||||
settings.SESSION_COOKIE_NAME,
|
||||
request.session.session_key, max_age=max_age,
|
||||
expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
|
||||
path=settings.SESSION_COOKIE_PATH,
|
||||
secure=settings.SESSION_COOKIE_SECURE or None,
|
||||
httponly=settings.SESSION_COOKIE_HTTPONLY or None,
|
||||
)
|
||||
return response
|
||||
|
@ -85,8 +85,12 @@ class SiteManager(models.Manager):
|
||||
@python_2_unicode_compatible
|
||||
class Site(models.Model):
|
||||
|
||||
domain = models.CharField(_('domain name'), max_length=100,
|
||||
validators=[_simple_domain_name_validator], unique=True)
|
||||
domain = models.CharField(
|
||||
_('domain name'),
|
||||
max_length=100,
|
||||
validators=[_simple_domain_name_validator],
|
||||
unique=True,
|
||||
)
|
||||
name = models.CharField(_('display name'), max_length=50)
|
||||
objects = SiteManager()
|
||||
|
||||
|
@ -39,30 +39,43 @@ class Command(BaseCommand):
|
||||
return True
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--noinput', '--no-input',
|
||||
parser.add_argument(
|
||||
'--noinput', '--no-input',
|
||||
action='store_false', dest='interactive', default=True,
|
||||
help="Do NOT prompt the user for input of any kind.")
|
||||
parser.add_argument('--no-post-process',
|
||||
help="Do NOT prompt the user for input of any kind.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-post-process',
|
||||
action='store_false', dest='post_process', default=True,
|
||||
help="Do NOT post process collected files.")
|
||||
parser.add_argument('-i', '--ignore', action='append', default=[],
|
||||
help="Do NOT post process collected files.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'-i', '--ignore', action='append', default=[],
|
||||
dest='ignore_patterns', metavar='PATTERN',
|
||||
help="Ignore files or directories matching this glob-style "
|
||||
"pattern. Use multiple times to ignore more.")
|
||||
parser.add_argument('-n', '--dry-run',
|
||||
"pattern. Use multiple times to ignore more.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'-n', '--dry-run',
|
||||
action='store_true', dest='dry_run', default=False,
|
||||
help="Do everything except modify the filesystem.")
|
||||
parser.add_argument('-c', '--clear',
|
||||
help="Do everything except modify the filesystem.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'-c', '--clear',
|
||||
action='store_true', dest='clear', default=False,
|
||||
help="Clear the existing files using the storage "
|
||||
"before trying to copy or link the original file.")
|
||||
parser.add_argument('-l', '--link',
|
||||
"before trying to copy or link the original file.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'-l', '--link',
|
||||
action='store_true', dest='link', default=False,
|
||||
help="Create a symbolic link to each file instead of copying.")
|
||||
parser.add_argument('--no-default-ignore', action='store_false',
|
||||
help="Create a symbolic link to each file instead of copying.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-default-ignore', action='store_false',
|
||||
dest='use_default_ignore_patterns', default=True,
|
||||
help="Don't ignore the common private glob-style patterns 'CVS', "
|
||||
"'.*' and '*~'.")
|
||||
help="Don't ignore the common private glob-style patterns 'CVS', '.*' and '*~'.",
|
||||
)
|
||||
|
||||
def set_options(self, **options):
|
||||
"""
|
||||
|
@ -13,18 +13,21 @@ class Command(LabelCommand):
|
||||
|
||||
def add_arguments(self, parser):
|
||||
super(Command, self).add_arguments(parser)
|
||||
parser.add_argument('--first', action='store_false', dest='all',
|
||||
parser.add_argument(
|
||||
'--first', action='store_false', dest='all',
|
||||
default=True,
|
||||
help="Only return the first match for each static file.")
|
||||
help="Only return the first match for each static file.",
|
||||
)
|
||||
|
||||
def handle_label(self, path, **options):
|
||||
verbosity = options['verbosity']
|
||||
result = finders.find(path, all=options['all'])
|
||||
path = force_text(path)
|
||||
if verbosity >= 2:
|
||||
searched_locations = ("\nLooking in the following locations:\n %s" %
|
||||
"\n ".join(force_text(location)
|
||||
for location in finders.searched_locations))
|
||||
searched_locations = (
|
||||
"\nLooking in the following locations:\n %s" %
|
||||
"\n ".join(force_text(location) for location in finders.searched_locations)
|
||||
)
|
||||
else:
|
||||
searched_locations = ''
|
||||
if result:
|
||||
|
@ -9,10 +9,14 @@ class Command(RunserverCommand):
|
||||
|
||||
def add_arguments(self, parser):
|
||||
super(Command, self).add_arguments(parser)
|
||||
parser.add_argument('--nostatic', action="store_false", dest='use_static_handler', default=True,
|
||||
help='Tells Django to NOT automatically serve static files at STATIC_URL.')
|
||||
parser.add_argument('--insecure', action="store_true", dest='insecure_serving', default=False,
|
||||
help='Allows serving static files even if DEBUG is False.')
|
||||
parser.add_argument(
|
||||
'--nostatic', action="store_false", dest='use_static_handler', default=True,
|
||||
help='Tells Django to NOT automatically serve static files at STATIC_URL.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--insecure', action="store_true", dest='insecure_serving', default=False,
|
||||
help='Allows serving static files even if DEBUG is False.',
|
||||
)
|
||||
|
||||
def get_handler(self, *args, **options):
|
||||
"""
|
||||
|
14
django/core/cache/backends/base.py
vendored
14
django/core/cache/backends/base.py
vendored
@ -234,14 +234,16 @@ class BaseCache(object):
|
||||
cache code.
|
||||
"""
|
||||
if len(key) > MEMCACHE_MAX_KEY_LENGTH:
|
||||
warnings.warn('Cache key will cause errors if used with memcached: '
|
||||
'%r (longer than %s)' % (key, MEMCACHE_MAX_KEY_LENGTH),
|
||||
CacheKeyWarning)
|
||||
warnings.warn(
|
||||
'Cache key will cause errors if used with memcached: %r '
|
||||
'(longer than %s)' % (key, MEMCACHE_MAX_KEY_LENGTH), CacheKeyWarning
|
||||
)
|
||||
for char in key:
|
||||
if ord(char) < 33 or ord(char) == 127:
|
||||
warnings.warn('Cache key contains characters that will cause '
|
||||
'errors if used with memcached: %r' % key,
|
||||
CacheKeyWarning)
|
||||
warnings.warn(
|
||||
'Cache key contains characters that will cause errors if '
|
||||
'used with memcached: %r' % key, CacheKeyWarning
|
||||
)
|
||||
break
|
||||
|
||||
def incr_version(self, key, delta=1, version=None):
|
||||
|
@ -35,8 +35,7 @@ if os.name == 'nt':
|
||||
Python 2.6+, or the 'delete', 'buffering', 'encoding', or 'newline'
|
||||
keyword arguments in Python 3.0+.
|
||||
"""
|
||||
def __init__(self, mode='w+b', bufsize=-1, suffix='', prefix='',
|
||||
dir=None):
|
||||
def __init__(self, mode='w+b', bufsize=-1, suffix='', prefix='', dir=None):
|
||||
fd, name = tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir)
|
||||
self.name = name
|
||||
self.file = os.fdopen(fd, mode, bufsize)
|
||||
|
@ -62,8 +62,7 @@ class TemporaryUploadedFile(UploadedFile):
|
||||
"""
|
||||
def __init__(self, name, content_type, size, charset, content_type_extra=None):
|
||||
if settings.FILE_UPLOAD_TEMP_DIR:
|
||||
file = tempfile.NamedTemporaryFile(suffix='.upload',
|
||||
dir=settings.FILE_UPLOAD_TEMP_DIR)
|
||||
file = tempfile.NamedTemporaryFile(suffix='.upload', dir=settings.FILE_UPLOAD_TEMP_DIR)
|
||||
else:
|
||||
file = tempfile.NamedTemporaryFile(suffix='.upload')
|
||||
super(TemporaryUploadedFile, self).__init__(file, name, content_type, size, charset, content_type_extra)
|
||||
|
@ -154,8 +154,10 @@ class BaseHandler(object):
|
||||
view_name = callback.__name__
|
||||
else: # CBV
|
||||
view_name = callback.__class__.__name__ + '.__call__'
|
||||
raise ValueError("The view %s.%s didn't return an HttpResponse object. It returned None instead."
|
||||
% (callback.__module__, view_name))
|
||||
raise ValueError(
|
||||
"The view %s.%s didn't return an HttpResponse object. It "
|
||||
"returned None instead." % (callback.__module__, view_name)
|
||||
)
|
||||
|
||||
# If the response supports deferred rendering, apply template
|
||||
# response middleware and then render the response
|
||||
@ -167,7 +169,8 @@ class BaseHandler(object):
|
||||
raise ValueError(
|
||||
"%s.process_template_response didn't return an "
|
||||
"HttpResponse object. It returned None instead."
|
||||
% (middleware_method.__self__.__class__.__name__))
|
||||
% (middleware_method.__self__.__class__.__name__)
|
||||
)
|
||||
try:
|
||||
response = response.render()
|
||||
except Exception as e:
|
||||
@ -176,11 +179,10 @@ class BaseHandler(object):
|
||||
response_is_rendered = True
|
||||
|
||||
except http.Http404 as exc:
|
||||
logger.warning('Not Found: %s', request.path,
|
||||
extra={
|
||||
'status_code': 404,
|
||||
'request': request
|
||||
})
|
||||
logger.warning(
|
||||
'Not Found: %s', request.path,
|
||||
extra={'status_code': 404, 'request': request},
|
||||
)
|
||||
if settings.DEBUG:
|
||||
response = debug.technical_404_response(request, exc)
|
||||
else:
|
||||
@ -189,32 +191,25 @@ class BaseHandler(object):
|
||||
except PermissionDenied as exc:
|
||||
logger.warning(
|
||||
'Forbidden (Permission denied): %s', request.path,
|
||||
extra={
|
||||
'status_code': 403,
|
||||
'request': request
|
||||
})
|
||||
extra={'status_code': 403, 'request': request},
|
||||
)
|
||||
response = self.get_exception_response(request, resolver, 403, exc)
|
||||
|
||||
except MultiPartParserError as exc:
|
||||
logger.warning(
|
||||
'Bad request (Unable to parse request body): %s', request.path,
|
||||
extra={
|
||||
'status_code': 400,
|
||||
'request': request
|
||||
})
|
||||
extra={'status_code': 400, 'request': request},
|
||||
)
|
||||
response = self.get_exception_response(request, resolver, 400, exc)
|
||||
|
||||
except SuspiciousOperation as exc:
|
||||
# The request logger receives events for any problematic request
|
||||
# The security logger receives events for all SuspiciousOperations
|
||||
security_logger = logging.getLogger('django.security.%s' %
|
||||
exc.__class__.__name__)
|
||||
security_logger = logging.getLogger('django.security.%s' % exc.__class__.__name__)
|
||||
security_logger.error(
|
||||
force_text(exc),
|
||||
extra={
|
||||
'status_code': 400,
|
||||
'request': request
|
||||
})
|
||||
extra={'status_code': 400, 'request': request},
|
||||
)
|
||||
if settings.DEBUG:
|
||||
return debug.technical_500_response(request, *sys.exc_info(), status_code=400)
|
||||
|
||||
@ -277,12 +272,10 @@ class BaseHandler(object):
|
||||
if settings.DEBUG_PROPAGATE_EXCEPTIONS:
|
||||
raise
|
||||
|
||||
logger.error('Internal Server Error: %s', request.path,
|
||||
logger.error(
|
||||
'Internal Server Error: %s', request.path,
|
||||
exc_info=exc_info,
|
||||
extra={
|
||||
'status_code': 500,
|
||||
'request': request
|
||||
}
|
||||
extra={'status_code': 500, 'request': request},
|
||||
)
|
||||
|
||||
if settings.DEBUG:
|
||||
|
@ -158,7 +158,8 @@ class WSGIHandler(base.BaseHandler):
|
||||
try:
|
||||
request = self.request_class(environ)
|
||||
except UnicodeDecodeError:
|
||||
logger.warning('Bad Request (UnicodeDecodeError)',
|
||||
logger.warning(
|
||||
'Bad Request (UnicodeDecodeError)',
|
||||
exc_info=sys.exc_info(),
|
||||
extra={
|
||||
'status_code': 400,
|
||||
|
@ -50,11 +50,12 @@ def send_mail(subject, message, from_email, recipient_list,
|
||||
Note: The API for this method is frozen. New code wanting to extend the
|
||||
functionality should use the EmailMessage class directly.
|
||||
"""
|
||||
connection = connection or get_connection(username=auth_user,
|
||||
password=auth_password,
|
||||
fail_silently=fail_silently)
|
||||
mail = EmailMultiAlternatives(subject, message, from_email, recipient_list,
|
||||
connection=connection)
|
||||
connection = connection or get_connection(
|
||||
username=auth_user,
|
||||
password=auth_password,
|
||||
fail_silently=fail_silently,
|
||||
)
|
||||
mail = EmailMultiAlternatives(subject, message, from_email, recipient_list, connection=connection)
|
||||
if html_message:
|
||||
mail.attach_alternative(html_message, 'text/html')
|
||||
|
||||
@ -75,12 +76,15 @@ def send_mass_mail(datatuple, fail_silently=False, auth_user=None,
|
||||
Note: The API for this method is frozen. New code wanting to extend the
|
||||
functionality should use the EmailMessage class directly.
|
||||
"""
|
||||
connection = connection or get_connection(username=auth_user,
|
||||
password=auth_password,
|
||||
fail_silently=fail_silently)
|
||||
messages = [EmailMessage(subject, message, sender, recipient,
|
||||
connection=connection)
|
||||
for subject, message, sender, recipient in datatuple]
|
||||
connection = connection or get_connection(
|
||||
username=auth_user,
|
||||
password=auth_password,
|
||||
fail_silently=fail_silently,
|
||||
)
|
||||
messages = [
|
||||
EmailMessage(subject, message, sender, recipient, connection=connection)
|
||||
for subject, message, sender, recipient in datatuple
|
||||
]
|
||||
return connection.send_messages(messages)
|
||||
|
||||
|
||||
@ -89,9 +93,11 @@ def mail_admins(subject, message, fail_silently=False, connection=None,
|
||||
"""Sends a message to the admins, as defined by the ADMINS setting."""
|
||||
if not settings.ADMINS:
|
||||
return
|
||||
mail = EmailMultiAlternatives('%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
|
||||
message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS],
|
||||
connection=connection)
|
||||
mail = EmailMultiAlternatives(
|
||||
'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject), message,
|
||||
settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS],
|
||||
connection=connection,
|
||||
)
|
||||
if html_message:
|
||||
mail.attach_alternative(html_message, 'text/html')
|
||||
mail.send(fail_silently=fail_silently)
|
||||
@ -102,9 +108,11 @@ def mail_managers(subject, message, fail_silently=False, connection=None,
|
||||
"""Sends a message to the managers, as defined by the MANAGERS setting."""
|
||||
if not settings.MANAGERS:
|
||||
return
|
||||
mail = EmailMultiAlternatives('%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
|
||||
message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS],
|
||||
connection=connection)
|
||||
mail = EmailMultiAlternatives(
|
||||
'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject), message,
|
||||
settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS],
|
||||
connection=connection,
|
||||
)
|
||||
if html_message:
|
||||
mail.attach_alternative(html_message, 'text/html')
|
||||
mail.send(fail_silently=fail_silently)
|
||||
|
@ -90,8 +90,7 @@ def forbid_multi_line_headers(name, val, encoding):
|
||||
val.encode('ascii')
|
||||
except UnicodeEncodeError:
|
||||
if name.lower() in ADDRESS_HEADERS:
|
||||
val = ', '.join(sanitize_address(addr, encoding)
|
||||
for addr in getaddresses((val,)))
|
||||
val = ', '.join(sanitize_address(addr, encoding) for addr in getaddresses((val,)))
|
||||
else:
|
||||
val = Header(val, encoding).encode()
|
||||
else:
|
||||
@ -418,8 +417,8 @@ class EmailMultiAlternatives(EmailMessage):
|
||||
alternative_subtype = 'alternative'
|
||||
|
||||
def __init__(self, subject='', body='', from_email=None, to=None, bcc=None,
|
||||
connection=None, attachments=None, headers=None, alternatives=None,
|
||||
cc=None, reply_to=None):
|
||||
connection=None, attachments=None, headers=None, alternatives=None,
|
||||
cc=None, reply_to=None):
|
||||
"""
|
||||
Initialize a single email message (which can be sent to multiple
|
||||
recipients).
|
||||
|
@ -196,8 +196,10 @@ class ManagementUtility(object):
|
||||
settings.INSTALLED_APPS
|
||||
else:
|
||||
sys.stderr.write("No Django settings specified.\n")
|
||||
sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" %
|
||||
(subcommand, self.prog_name))
|
||||
sys.stderr.write(
|
||||
"Unknown command: %r\nType '%s help' for usage.\n"
|
||||
% (subcommand, self.prog_name)
|
||||
)
|
||||
sys.exit(1)
|
||||
if isinstance(app_name, BaseCommand):
|
||||
# If the command is already loaded, use it directly.
|
||||
|
@ -241,25 +241,33 @@ class BaseCommand(object):
|
||||
Create and return the ``ArgumentParser`` which will be used to
|
||||
parse the arguments to this command.
|
||||
"""
|
||||
parser = CommandParser(self, prog="%s %s" % (os.path.basename(prog_name), subcommand),
|
||||
description=self.help or None)
|
||||
parser = CommandParser(
|
||||
self, prog="%s %s" % (os.path.basename(prog_name), subcommand),
|
||||
description=self.help or None,
|
||||
)
|
||||
parser.add_argument('--version', action='version', version=self.get_version())
|
||||
parser.add_argument('-v', '--verbosity', action='store', dest='verbosity', default=1,
|
||||
parser.add_argument(
|
||||
'-v', '--verbosity', action='store', dest='verbosity', default=1,
|
||||
type=int, choices=[0, 1, 2, 3],
|
||||
help='Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output')
|
||||
parser.add_argument('--settings',
|
||||
help='Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--settings',
|
||||
help=(
|
||||
'The Python path to a settings module, e.g. '
|
||||
'"myproject.settings.main". If this isn\'t provided, the '
|
||||
'DJANGO_SETTINGS_MODULE environment variable will be used.'
|
||||
),
|
||||
)
|
||||
parser.add_argument('--pythonpath',
|
||||
help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".')
|
||||
parser.add_argument('--traceback', action='store_true',
|
||||
help='Raise on CommandError exceptions')
|
||||
parser.add_argument('--no-color', action='store_true', dest='no_color', default=False,
|
||||
help="Don't colorize the command output.")
|
||||
parser.add_argument(
|
||||
'--pythonpath',
|
||||
help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".',
|
||||
)
|
||||
parser.add_argument('--traceback', action='store_true', help='Raise on CommandError exceptions')
|
||||
parser.add_argument(
|
||||
'--no-color', action='store_true', dest='no_color', default=False,
|
||||
help="Don't colorize the command output.",
|
||||
)
|
||||
self.add_arguments(parser)
|
||||
return parser
|
||||
|
||||
@ -478,8 +486,7 @@ class AppCommand(BaseCommand):
|
||||
missing_args_message = "Enter at least one application label."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('args', metavar='app_label', nargs='+',
|
||||
help='One or more application label.')
|
||||
parser.add_argument('args', metavar='app_label', nargs='+', help='One or more application label.')
|
||||
|
||||
def handle(self, *app_labels, **options):
|
||||
from django.apps import apps
|
||||
|
@ -14,12 +14,18 @@ class Command(BaseCommand):
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('args', metavar='app_label', nargs='*')
|
||||
parser.add_argument('--tag', '-t', action='append', dest='tags',
|
||||
help='Run only checks labeled with given tag.')
|
||||
parser.add_argument('--list-tags', action='store_true', dest='list_tags',
|
||||
help='List available tags.')
|
||||
parser.add_argument('--deploy', action='store_true', dest='deploy',
|
||||
help='Check deployment settings.')
|
||||
parser.add_argument(
|
||||
'--tag', '-t', action='append', dest='tags',
|
||||
help='Run only checks labeled with given tag.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--list-tags', action='store_true', dest='list_tags',
|
||||
help='List available tags.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--deploy', action='store_true', dest='deploy',
|
||||
help='Check deployment settings.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--fail-level',
|
||||
default='ERROR',
|
||||
|
@ -36,13 +36,19 @@ class Command(BaseCommand):
|
||||
program_options = ['--check-format']
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--locale', '-l', dest='locale', action='append', default=[],
|
||||
parser.add_argument(
|
||||
'--locale', '-l', dest='locale', action='append', default=[],
|
||||
help='Locale(s) to process (e.g. de_AT). Default is to process all. '
|
||||
'Can be used multiple times.')
|
||||
parser.add_argument('--exclude', '-x', dest='exclude', action='append', default=[],
|
||||
help='Locales to exclude. Default is none. Can be used multiple times.')
|
||||
parser.add_argument('--use-fuzzy', '-f', dest='fuzzy', action='store_true', default=False,
|
||||
help='Use fuzzy translations.')
|
||||
'Can be used multiple times.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--exclude', '-x', dest='exclude', action='append', default=[],
|
||||
help='Locales to exclude. Default is none. Can be used multiple times.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--use-fuzzy', '-f', dest='fuzzy', action='store_true', default=False,
|
||||
help='Use fuzzy translations.',
|
||||
)
|
||||
|
||||
def handle(self, **options):
|
||||
locale = options['locale']
|
||||
@ -116,8 +122,9 @@ class Command(BaseCommand):
|
||||
"mo files will not be updated/created." % dirpath)
|
||||
return
|
||||
|
||||
args = [self.program] + self.program_options + ['-o',
|
||||
npath(base_path + '.mo'), npath(base_path + '.po')]
|
||||
args = [self.program] + self.program_options + [
|
||||
'-o', npath(base_path + '.mo'), npath(base_path + '.po')
|
||||
]
|
||||
output, errors, status = popen_wrapper(args)
|
||||
if status:
|
||||
if errors:
|
||||
|
@ -15,16 +15,20 @@ class Command(BaseCommand):
|
||||
requires_system_checks = False
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('args', metavar='table_name', nargs='*',
|
||||
help='Optional table names. Otherwise, settings.CACHES is used to '
|
||||
'find cache tables.')
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
parser.add_argument(
|
||||
'args', metavar='table_name', nargs='*',
|
||||
help='Optional table names. Otherwise, settings.CACHES is used to find cache tables.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database onto which the cache tables will be '
|
||||
'installed. Defaults to the "default" database.')
|
||||
parser.add_argument('--dry-run', action='store_true', dest='dry_run',
|
||||
help='Does not create the table, just prints the SQL that would '
|
||||
'be run.')
|
||||
'installed. Defaults to the "default" database.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--dry-run', action='store_true', dest='dry_run',
|
||||
help='Does not create the table, just prints the SQL that would be run.',
|
||||
)
|
||||
|
||||
def handle(self, *tablenames, **options):
|
||||
db = options['database']
|
||||
@ -72,9 +76,10 @@ class Command(BaseCommand):
|
||||
field_output.append("UNIQUE")
|
||||
if f.db_index:
|
||||
unique = "UNIQUE " if f.unique else ""
|
||||
index_output.append("CREATE %sINDEX %s ON %s (%s);" %
|
||||
(unique, qn('%s_%s' % (tablename, f.name)), qn(tablename),
|
||||
qn(f.name)))
|
||||
index_output.append(
|
||||
"CREATE %sINDEX %s ON %s (%s);" %
|
||||
(unique, qn('%s_%s' % (tablename, f.name)), qn(tablename), qn(f.name))
|
||||
)
|
||||
table_output.append(" ".join(field_output))
|
||||
full_statement = ["CREATE TABLE %s (" % qn(tablename)]
|
||||
for i, line in enumerate(table_output):
|
||||
@ -89,8 +94,7 @@ class Command(BaseCommand):
|
||||
self.stdout.write(statement)
|
||||
return
|
||||
|
||||
with transaction.atomic(using=database,
|
||||
savepoint=connection.features.can_rollback_ddl):
|
||||
with transaction.atomic(using=database, savepoint=connection.features.can_rollback_ddl):
|
||||
with connection.cursor() as curs:
|
||||
try:
|
||||
curs.execute(full_statement)
|
||||
|
@ -3,15 +3,18 @@ from django.db import DEFAULT_DB_ALIAS, connections
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ("Runs the command-line client for specified database, or the "
|
||||
"default database if none is provided.")
|
||||
help = (
|
||||
"Runs the command-line client for specified database, or the "
|
||||
"default database if none is provided."
|
||||
)
|
||||
|
||||
requires_system_checks = False
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database onto which to '
|
||||
'open a shell. Defaults to the "default" database.')
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database onto which to open a shell. Defaults to the "default" database.',
|
||||
)
|
||||
|
||||
def handle(self, **options):
|
||||
connection = connections[options['database']]
|
||||
@ -22,5 +25,7 @@ class Command(BaseCommand):
|
||||
# isn't installed. There's a possibility OSError would be raised
|
||||
# for some other reason, in which case this error message would be
|
||||
# inaccurate. Still, this message catches the common case.
|
||||
raise CommandError('You appear not to have the %r program installed or on your path.' %
|
||||
connection.client.executable_name)
|
||||
raise CommandError(
|
||||
'You appear not to have the %r program installed or on your path.' %
|
||||
connection.client.executable_name
|
||||
)
|
||||
|
@ -14,9 +14,10 @@ class Command(BaseCommand):
|
||||
requires_system_checks = False
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--all', action='store_true', dest='all', default=False,
|
||||
help='Display all settings, regardless of their value. '
|
||||
'Default values are prefixed by "###".')
|
||||
parser.add_argument(
|
||||
'--all', action='store_true', dest='all', default=False,
|
||||
help='Display all settings, regardless of their value. Default values are prefixed by "###".',
|
||||
)
|
||||
|
||||
def handle(self, **options):
|
||||
# Inspired by Postfix's "postconf -n".
|
||||
|
@ -12,37 +12,57 @@ class ProxyModelWarning(Warning):
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ("Output the contents of the database as a fixture of the given "
|
||||
"format (using each model's default manager unless --all is "
|
||||
"specified).")
|
||||
help = (
|
||||
"Output the contents of the database as a fixture of the given format "
|
||||
"(using each model's default manager unless --all is specified)."
|
||||
)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('args', metavar='app_label[.ModelName]', nargs='*',
|
||||
help='Restricts dumped data to the specified app_label or app_label.ModelName.')
|
||||
parser.add_argument('--format', default='json', dest='format',
|
||||
help='Specifies the output serialization format for fixtures.')
|
||||
parser.add_argument('--indent', default=None, dest='indent', type=int,
|
||||
help='Specifies the indent level to use when pretty-printing output.')
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
parser.add_argument(
|
||||
'args', metavar='app_label[.ModelName]', nargs='*',
|
||||
help='Restricts dumped data to the specified app_label or app_label.ModelName.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--format', default='json', dest='format',
|
||||
help='Specifies the output serialization format for fixtures.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--indent', default=None, dest='indent', type=int,
|
||||
help='Specifies the indent level to use when pretty-printing output.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a specific database to dump fixtures from. '
|
||||
'Defaults to the "default" database.')
|
||||
parser.add_argument('-e', '--exclude', dest='exclude', action='append', default=[],
|
||||
'Defaults to the "default" database.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-e', '--exclude', dest='exclude', action='append', default=[],
|
||||
help='An app_label or app_label.ModelName to exclude '
|
||||
'(use multiple --exclude to exclude multiple apps/models).')
|
||||
parser.add_argument('--natural-foreign', action='store_true', dest='use_natural_foreign_keys', default=False,
|
||||
help='Use natural foreign keys if they are available.')
|
||||
parser.add_argument('--natural-primary', action='store_true', dest='use_natural_primary_keys', default=False,
|
||||
help='Use natural primary keys if they are available.')
|
||||
parser.add_argument('-a', '--all', action='store_true', dest='use_base_manager', default=False,
|
||||
'(use multiple --exclude to exclude multiple apps/models).',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--natural-foreign', action='store_true', dest='use_natural_foreign_keys', default=False,
|
||||
help='Use natural foreign keys if they are available.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--natural-primary', action='store_true', dest='use_natural_primary_keys', default=False,
|
||||
help='Use natural primary keys if they are available.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-a', '--all', action='store_true', dest='use_base_manager', default=False,
|
||||
help="Use Django's base manager to dump all models stored in the database, "
|
||||
"including those that would otherwise be filtered or modified by a custom manager.")
|
||||
parser.add_argument('--pks', dest='primary_keys',
|
||||
help="Only dump objects with given primary keys. "
|
||||
"Accepts a comma separated list of keys. "
|
||||
"This option will only work when you specify one model.")
|
||||
parser.add_argument('-o', '--output', default=None, dest='output',
|
||||
help='Specifies file to which the output is written.')
|
||||
"including those that would otherwise be filtered or modified by a custom manager.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--pks', dest='primary_keys',
|
||||
help="Only dump objects with given primary keys. Accepts a comma-separated "
|
||||
"list of keys. This option only works when you specify one model.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'-o', '--output', default=None, dest='output',
|
||||
help='Specifies file to which the output is written.'
|
||||
)
|
||||
|
||||
def handle(self, *app_labels, **options):
|
||||
format = options['format']
|
||||
@ -80,9 +100,10 @@ class Command(BaseCommand):
|
||||
if len(app_labels) == 0:
|
||||
if primary_keys:
|
||||
raise CommandError("You can only use --pks option with one model")
|
||||
app_list = OrderedDict((app_config, None)
|
||||
for app_config in apps.get_app_configs()
|
||||
if app_config.models_module is not None and app_config not in excluded_apps)
|
||||
app_list = OrderedDict(
|
||||
(app_config, None) for app_config in apps.get_app_configs()
|
||||
if app_config.models_module is not None and app_config not in excluded_apps
|
||||
)
|
||||
else:
|
||||
if len(app_labels) > 1 and primary_keys:
|
||||
raise CommandError("You can only use --pks option with one model")
|
||||
@ -171,11 +192,13 @@ class Command(BaseCommand):
|
||||
object_count = sum(get_objects(count_only=True))
|
||||
stream = open(output, 'w') if output else None
|
||||
try:
|
||||
serializers.serialize(format, get_objects(), indent=indent,
|
||||
use_natural_foreign_keys=use_natural_foreign_keys,
|
||||
use_natural_primary_keys=use_natural_primary_keys,
|
||||
stream=stream or self.stdout, progress_output=progress_output,
|
||||
object_count=object_count)
|
||||
serializers.serialize(
|
||||
format, get_objects(), indent=indent,
|
||||
use_natural_foreign_keys=use_natural_foreign_keys,
|
||||
use_natural_primary_keys=use_natural_primary_keys,
|
||||
stream=stream or self.stdout, progress_output=progress_output,
|
||||
object_count=object_count,
|
||||
)
|
||||
finally:
|
||||
if stream:
|
||||
stream.close()
|
||||
|
@ -13,16 +13,21 @@ from django.utils.six.moves import input
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ('Removes ALL DATA from the database, including data added during '
|
||||
'migrations. Does not achieve a "fresh install" state.')
|
||||
help = (
|
||||
'Removes ALL DATA from the database, including data added during '
|
||||
'migrations. Does not achieve a "fresh install" state.'
|
||||
)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--noinput', '--no-input',
|
||||
parser.add_argument(
|
||||
'--noinput', '--no-input',
|
||||
action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.')
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to flush. Defaults to the "default" database.')
|
||||
help='Tells Django to NOT prompt the user for input of any kind.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to flush. Defaults to the "default" database.',
|
||||
)
|
||||
|
||||
def handle(self, **options):
|
||||
database = options['database']
|
||||
|
@ -17,11 +17,14 @@ class Command(BaseCommand):
|
||||
db_module = 'django.db'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('table', action='store', nargs='*', type=str,
|
||||
help='Selects what tables or views should be introspected.')
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to '
|
||||
'introspect. Defaults to using the "default" database.')
|
||||
parser.add_argument(
|
||||
'table', action='store', nargs='*', type=str,
|
||||
help='Selects what tables or views should be introspected.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to introspect. Defaults to using the "default" database.',
|
||||
)
|
||||
|
||||
def handle(self, **options):
|
||||
try:
|
||||
|
@ -32,21 +32,26 @@ except ImportError:
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Installs the named fixture(s) in the database.'
|
||||
missing_args_message = ("No database fixture specified. Please provide the "
|
||||
"path of at least one fixture in the command line.")
|
||||
missing_args_message = (
|
||||
"No database fixture specified. Please provide the path of at least "
|
||||
"one fixture in the command line."
|
||||
)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('args', metavar='fixture', nargs='+',
|
||||
help='Fixture labels.')
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load '
|
||||
'fixtures into. Defaults to the "default" database.')
|
||||
parser.add_argument('--app', action='store', dest='app_label',
|
||||
default=None, help='Only look for fixtures in the specified app.')
|
||||
parser.add_argument('--ignorenonexistent', '-i', action='store_true',
|
||||
dest='ignore', default=False,
|
||||
parser.add_argument('args', metavar='fixture', nargs='+', help='Fixture labels.')
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a specific database to load fixtures into. Defaults to the "default" database.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--app', action='store', dest='app_label', default=None,
|
||||
help='Only look for fixtures in the specified app.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--ignorenonexistent', '-i', action='store_true', dest='ignore', default=False,
|
||||
help='Ignores entries in the serialized data for fields that do not '
|
||||
'currently exist on the model.')
|
||||
'currently exist on the model.',
|
||||
)
|
||||
|
||||
def handle(self, *fixture_labels, **options):
|
||||
|
||||
@ -120,11 +125,15 @@ class Command(BaseCommand):
|
||||
|
||||
if self.verbosity >= 1:
|
||||
if self.fixture_object_count == self.loaded_object_count:
|
||||
self.stdout.write("Installed %d object(s) from %d fixture(s)" %
|
||||
(self.loaded_object_count, self.fixture_count))
|
||||
self.stdout.write(
|
||||
"Installed %d object(s) from %d fixture(s)"
|
||||
% (self.loaded_object_count, self.fixture_count)
|
||||
)
|
||||
else:
|
||||
self.stdout.write("Installed %d object(s) (of %d) from %d fixture(s)" %
|
||||
(self.loaded_object_count, self.fixture_object_count, self.fixture_count))
|
||||
self.stdout.write(
|
||||
"Installed %d object(s) (of %d) from %d fixture(s)"
|
||||
% (self.loaded_object_count, self.fixture_object_count, self.fixture_count)
|
||||
)
|
||||
|
||||
def load_label(self, fixture_label):
|
||||
"""
|
||||
@ -140,11 +149,14 @@ class Command(BaseCommand):
|
||||
objects_in_fixture = 0
|
||||
loaded_objects_in_fixture = 0
|
||||
if self.verbosity >= 2:
|
||||
self.stdout.write("Installing %s fixture '%s' from %s." %
|
||||
(ser_fmt, fixture_name, humanize(fixture_dir)))
|
||||
self.stdout.write(
|
||||
"Installing %s fixture '%s' from %s."
|
||||
% (ser_fmt, fixture_name, humanize(fixture_dir))
|
||||
)
|
||||
|
||||
objects = serializers.deserialize(ser_fmt, fixture,
|
||||
using=self.using, ignorenonexistent=self.ignore)
|
||||
objects = serializers.deserialize(
|
||||
ser_fmt, fixture, using=self.using, ignorenonexistent=self.ignore,
|
||||
)
|
||||
|
||||
for obj in objects:
|
||||
objects_in_fixture += 1
|
||||
@ -208,8 +220,10 @@ class Command(BaseCommand):
|
||||
for dir_ in fixture_dirs]
|
||||
fixture_name = os.path.basename(fixture_name)
|
||||
|
||||
suffixes = ('.'.join(ext for ext in combo if ext)
|
||||
for combo in product(databases, ser_fmts, cmp_fmts))
|
||||
suffixes = (
|
||||
'.'.join(ext for ext in combo if ext)
|
||||
for combo in product(databases, ser_fmts, cmp_fmts)
|
||||
)
|
||||
targets = set('.'.join((fixture_name, suffix)) for suffix in suffixes)
|
||||
|
||||
fixture_files = []
|
||||
|
@ -30,8 +30,10 @@ NO_LOCALE_DIR = object()
|
||||
def check_programs(*programs):
|
||||
for program in programs:
|
||||
if find_command(program) is None:
|
||||
raise CommandError("Can't find %s. Make sure you have GNU "
|
||||
"gettext tools 0.15 or newer installed." % program)
|
||||
raise CommandError(
|
||||
"Can't find %s. Make sure you have GNU gettext tools 0.15 or "
|
||||
"newer installed." % program
|
||||
)
|
||||
|
||||
|
||||
@total_ordering
|
||||
@ -161,11 +163,13 @@ def write_pot_file(potfile, msgs):
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ("Runs over the entire source tree of the current directory and "
|
||||
"pulls out all strings marked for translation. It creates (or updates) a message "
|
||||
"file in the conf/locale (in the django tree) or locale (for projects and "
|
||||
"applications) directory.\n\nYou must run this command with one of either the "
|
||||
"--locale, --exclude or --all options.")
|
||||
help = (
|
||||
"Runs over the entire source tree of the current directory and "
|
||||
"pulls out all strings marked for translation. It creates (or updates) a message "
|
||||
"file in the conf/locale (in the django tree) or locale (for projects and "
|
||||
"applications) directory.\n\nYou must run this command with one of either the "
|
||||
"--locale, --exclude, or --all options."
|
||||
)
|
||||
|
||||
translatable_file_class = TranslatableFile
|
||||
build_file_class = BuildFile
|
||||
@ -179,37 +183,60 @@ class Command(BaseCommand):
|
||||
xgettext_options = ['--from-code=UTF-8', '--add-comments=Translators']
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--locale', '-l', default=[], dest='locale', action='append',
|
||||
parser.add_argument(
|
||||
'--locale', '-l', default=[], dest='locale', action='append',
|
||||
help='Creates or updates the message files for the given locale(s) (e.g. pt_BR). '
|
||||
'Can be used multiple times.')
|
||||
parser.add_argument('--exclude', '-x', default=[], dest='exclude', action='append',
|
||||
help='Locales to exclude. Default is none. Can be used multiple times.')
|
||||
parser.add_argument('--domain', '-d', default='django', dest='domain',
|
||||
help='The domain of the message files (default: "django").')
|
||||
parser.add_argument('--all', '-a', action='store_true', dest='all',
|
||||
default=False, help='Updates the message files for all existing locales.')
|
||||
parser.add_argument('--extension', '-e', dest='extensions',
|
||||
'Can be used multiple times.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--exclude', '-x', default=[], dest='exclude', action='append',
|
||||
help='Locales to exclude. Default is none. Can be used multiple times.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--domain', '-d', default='django', dest='domain',
|
||||
help='The domain of the message files (default: "django").',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--all', '-a', action='store_true', dest='all', default=False,
|
||||
help='Updates the message files for all existing locales.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--extension', '-e', dest='extensions', action='append',
|
||||
help='The file extension(s) to examine (default: "html,txt,py", or "js" '
|
||||
'if the domain is "djangojs"). Separate multiple extensions with '
|
||||
'commas, or use -e multiple times.',
|
||||
action='append')
|
||||
parser.add_argument('--symlinks', '-s', action='store_true', dest='symlinks',
|
||||
default=False, help='Follows symlinks to directories when examining '
|
||||
'source code and templates for translation strings.')
|
||||
parser.add_argument('--ignore', '-i', action='append', dest='ignore_patterns',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--symlinks', '-s', action='store_true', dest='symlinks', default=False,
|
||||
help='Follows symlinks to directories when examining source code '
|
||||
'and templates for translation strings.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--ignore', '-i', action='append', dest='ignore_patterns',
|
||||
default=[], metavar='PATTERN',
|
||||
help='Ignore files or directories matching this glob-style pattern. '
|
||||
'Use multiple times to ignore more.')
|
||||
parser.add_argument('--no-default-ignore', action='store_false', dest='use_default_ignore_patterns',
|
||||
default=True, help="Don't ignore the common glob-style patterns 'CVS', '.*', '*~' and '*.pyc'.")
|
||||
parser.add_argument('--no-wrap', action='store_true', dest='no_wrap',
|
||||
default=False, help="Don't break long message lines into several lines.")
|
||||
parser.add_argument('--no-location', action='store_true', dest='no_location',
|
||||
default=False, help="Don't write '#: filename:line' lines.")
|
||||
parser.add_argument('--no-obsolete', action='store_true', dest='no_obsolete',
|
||||
default=False, help="Remove obsolete message strings.")
|
||||
parser.add_argument('--keep-pot', action='store_true', dest='keep_pot',
|
||||
default=False, help="Keep .pot file after making messages. Useful when debugging.")
|
||||
'Use multiple times to ignore more.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-default-ignore', action='store_false', dest='use_default_ignore_patterns',
|
||||
default=True, help="Don't ignore the common glob-style patterns 'CVS', '.*', '*~' and '*.pyc'.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-wrap', action='store_true', dest='no_wrap',
|
||||
default=False, help="Don't break long message lines into several lines.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-location', action='store_true', dest='no_location',
|
||||
default=False, help="Don't write '#: filename:line' lines.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-obsolete', action='store_true', dest='no_obsolete',
|
||||
default=False, help="Remove obsolete message strings.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--keep-pot', action='store_true', dest='keep_pot',
|
||||
default=False, help="Keep .pot file after making messages. Useful when debugging.",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
locale = options['locale']
|
||||
@ -256,12 +283,16 @@ class Command(BaseCommand):
|
||||
self.extensions = handle_extensions(exts)
|
||||
|
||||
if (locale is None and not exclude and not process_all) or self.domain is None:
|
||||
raise CommandError("Type '%s help %s' for usage information." % (
|
||||
os.path.basename(sys.argv[0]), sys.argv[1]))
|
||||
raise CommandError(
|
||||
"Type '%s help %s' for usage information."
|
||||
% (os.path.basename(sys.argv[0]), sys.argv[1])
|
||||
)
|
||||
|
||||
if self.verbosity > 1:
|
||||
self.stdout.write('examining files with the extensions: %s\n'
|
||||
% get_text_list(list(self.extensions), 'and'))
|
||||
self.stdout.write(
|
||||
'examining files with the extensions: %s\n'
|
||||
% get_text_list(list(self.extensions), 'and')
|
||||
)
|
||||
|
||||
self.invoked_for_django = False
|
||||
self.locale_paths = []
|
||||
|
@ -24,24 +24,40 @@ class Command(BaseCommand):
|
||||
help = "Creates new migration(s) for apps."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('args', metavar='app_label', nargs='*',
|
||||
help='Specify the app label(s) to create migrations for.')
|
||||
parser.add_argument('--dry-run', action='store_true', dest='dry_run', default=False,
|
||||
help="Just show what migrations would be made; don't actually write them.")
|
||||
parser.add_argument('--merge', action='store_true', dest='merge', default=False,
|
||||
help="Enable fixing of migration conflicts.")
|
||||
parser.add_argument('--empty', action='store_true', dest='empty', default=False,
|
||||
help="Create an empty migration.")
|
||||
parser.add_argument('--noinput', '--no-input',
|
||||
parser.add_argument(
|
||||
'args', metavar='app_label', nargs='*',
|
||||
help='Specify the app label(s) to create migrations for.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--dry-run', action='store_true', dest='dry_run', default=False,
|
||||
help="Just show what migrations would be made; don't actually write them.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--merge', action='store_true', dest='merge', default=False,
|
||||
help="Enable fixing of migration conflicts.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--empty', action='store_true', dest='empty', default=False,
|
||||
help="Create an empty migration.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--noinput', '--no-input',
|
||||
action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.')
|
||||
parser.add_argument('-n', '--name', action='store', dest='name', default=None,
|
||||
help="Use this name for migration file(s).")
|
||||
parser.add_argument('-e', '--exit', action='store_true', dest='exit_code', default=False,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-n', '--name', action='store', dest='name', default=None,
|
||||
help="Use this name for migration file(s).",
|
||||
)
|
||||
parser.add_argument(
|
||||
'-e', '--exit', action='store_true', dest='exit_code', default=False,
|
||||
help='Exit with error code 1 if no changes needing migrations are found. '
|
||||
'Deprecated, use the --check option instead.')
|
||||
parser.add_argument('--check', action='store_true', dest='check_changes',
|
||||
help='Exit with a non-zero status if model changes are missing migrations.')
|
||||
'Deprecated, use the --check option instead.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--check', action='store_true', dest='check_changes',
|
||||
help='Exit with a non-zero status if model changes are missing migrations.',
|
||||
)
|
||||
|
||||
def handle(self, *app_labels, **options):
|
||||
self.verbosity = options['verbosity']
|
||||
|
@ -22,28 +22,39 @@ class Command(BaseCommand):
|
||||
help = "Updates database schema. Manages both apps with migrations and those without."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('app_label', nargs='?',
|
||||
help='App label of an application to synchronize the state.')
|
||||
parser.add_argument('migration_name', nargs='?',
|
||||
help=(
|
||||
'Database state will be brought to the state after that '
|
||||
'migration. Use the name "zero" to unapply all migrations.'
|
||||
),
|
||||
parser.add_argument(
|
||||
'app_label', nargs='?',
|
||||
help='App label of an application to synchronize the state.',
|
||||
)
|
||||
parser.add_argument('--noinput', '--no-input',
|
||||
parser.add_argument(
|
||||
'migration_name', nargs='?',
|
||||
help='Database state will be brought to the state after that '
|
||||
'migration. Use the name "zero" to unapply all migrations.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--noinput', '--no-input',
|
||||
action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.')
|
||||
parser.add_argument('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to synchronize. '
|
||||
'Defaults to the "default" database.')
|
||||
parser.add_argument('--fake', action='store_true', dest='fake', default=False,
|
||||
help='Mark migrations as run without actually running them.')
|
||||
parser.add_argument('--fake-initial', action='store_true', dest='fake_initial', default=False,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to synchronize. Defaults to the "default" database.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--fake', action='store_true', dest='fake', default=False,
|
||||
help='Mark migrations as run without actually running them.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--fake-initial', action='store_true', dest='fake_initial', default=False,
|
||||
help='Detect if tables already exist and fake-apply initial migrations if so. Make sure '
|
||||
'that the current database schema matches your initial migration before using this '
|
||||
'flag. Django will only check for an existing table name.')
|
||||
parser.add_argument('--run-syncdb', action='store_true', dest='run_syncdb',
|
||||
help='Creates tables for apps without migrations.')
|
||||
'flag. Django will only check for an existing table name.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--run-syncdb', action='store_true', dest='run_syncdb',
|
||||
help='Creates tables for apps without migrations.',
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
@ -238,8 +249,10 @@ class Command(BaseCommand):
|
||||
opts = model._meta
|
||||
converter = connection.introspection.table_name_converter
|
||||
# Note that if a model is unmanaged we short-circuit and never try to install it
|
||||
return not ((converter(opts.db_table) in tables) or
|
||||
(opts.auto_created and converter(opts.auto_created._meta.db_table) in tables))
|
||||
return not (
|
||||
(converter(opts.db_table) in tables) or
|
||||
(opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)
|
||||
)
|
||||
|
||||
manifest = OrderedDict(
|
||||
(app_name, list(filter(model_installed, model_list)))
|
||||
|
@ -32,14 +32,22 @@ class Command(BaseCommand):
|
||||
default_port = '8000'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('addrport', nargs='?',
|
||||
help='Optional port number, or ipaddr:port')
|
||||
parser.add_argument('--ipv6', '-6', action='store_true', dest='use_ipv6', default=False,
|
||||
help='Tells Django to use an IPv6 address.')
|
||||
parser.add_argument('--nothreading', action='store_false', dest='use_threading', default=True,
|
||||
help='Tells Django to NOT use threading.')
|
||||
parser.add_argument('--noreload', action='store_false', dest='use_reloader', default=True,
|
||||
help='Tells Django to NOT use the auto-reloader.')
|
||||
parser.add_argument(
|
||||
'addrport', nargs='?',
|
||||
help='Optional port number, or ipaddr:port'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--ipv6', '-6', action='store_true', dest='use_ipv6', default=False,
|
||||
help='Tells Django to use an IPv6 address.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--nothreading', action='store_false', dest='use_threading', default=True,
|
||||
help='Tells Django to NOT use threading.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--noreload', action='store_false', dest='use_reloader', default=True,
|
||||
help='Tells Django to NOT use the auto-reloader.',
|
||||
)
|
||||
|
||||
def execute(self, *args, **options):
|
||||
if options['no_color']:
|
||||
|
@ -10,12 +10,18 @@ class Command(BaseCommand):
|
||||
missing_args_message = "You must specify some email recipients, or pass the --managers or --admin options."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('email', nargs='*',
|
||||
help='One or more email addresses to send a test email to.')
|
||||
parser.add_argument('--managers', action='store_true', dest='managers', default=False,
|
||||
help='Send a test email to the addresses specified in settings.MANAGERS.')
|
||||
parser.add_argument('--admins', action='store_true', dest='admins', default=False,
|
||||
help='Send a test email to the addresses specified in settings.ADMINS.')
|
||||
parser.add_argument(
|
||||
'email', nargs='*',
|
||||
help='One or more email addresses to send a test email to.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--managers', action='store_true', dest='managers', default=False,
|
||||
help='Send a test email to the addresses specified in settings.MANAGERS.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--admins', action='store_true', dest='admins', default=False,
|
||||
help='Send a test email to the addresses specified in settings.ADMINS.',
|
||||
)
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
subject = 'Test email from %s on %s' % (socket.gethostname(), timezone.now())
|
||||
|
@ -11,15 +11,23 @@ class Command(BaseCommand):
|
||||
shells = ['ipython', 'bpython', 'python']
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--plain', action='store_true', dest='plain',
|
||||
parser.add_argument(
|
||||
'--plain', action='store_true', dest='plain',
|
||||
help='Tells Django to use plain Python, not IPython or bpython. '
|
||||
'Deprecated, use the `-i python` or `--interface python` option instead.')
|
||||
parser.add_argument('--no-startup', action='store_true', dest='no_startup',
|
||||
help='When using plain Python, ignore the PYTHONSTARTUP environment variable and ~/.pythonrc.py script.')
|
||||
parser.add_argument('-i', '--interface', choices=self.shells, dest='interface',
|
||||
help='Specify an interactive interpreter interface. Available options: "ipython", "bpython", and "python"')
|
||||
parser.add_argument('-c', '--command', dest='command',
|
||||
help='Instead of opening an interactive shell, run a command as Django and exit.')
|
||||
'Deprecated, use the `-i python` or `--interface python` option instead.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-startup', action='store_true', dest='no_startup',
|
||||
help='When using plain Python, ignore the PYTHONSTARTUP environment variable and ~/.pythonrc.py script.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-i', '--interface', choices=self.shells, dest='interface',
|
||||
help='Specify an interactive interpreter interface. Available options: "ipython", "bpython", and "python"',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-c', '--command', dest='command',
|
||||
help='Instead of opening an interactive shell, run a command as Django and exit.',
|
||||
)
|
||||
|
||||
def _ipython_pre_011(self):
|
||||
"""Start IPython pre-0.11"""
|
||||
|
@ -10,16 +10,24 @@ class Command(BaseCommand):
|
||||
help = "Shows all available migrations for the current project"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('app_label', nargs='*',
|
||||
help='App labels of applications to limit the output to.')
|
||||
parser.add_argument('--database', action='store', dest='database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to synchronize. Defaults to the "default" database.')
|
||||
parser.add_argument(
|
||||
'app_label', nargs='*',
|
||||
help='App labels of applications to limit the output to.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--database', action='store', dest='database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to synchronize. Defaults to the "default" database.',
|
||||
)
|
||||
|
||||
formats = parser.add_mutually_exclusive_group()
|
||||
formats.add_argument('--list', '-l', action='store_const', dest='format', const='list',
|
||||
help='Shows a list of all migrations and which are applied.')
|
||||
formats.add_argument('--plan', '-p', action='store_const', dest='format', const='plan',
|
||||
help='Shows all migrations in the order they will be applied.')
|
||||
formats.add_argument(
|
||||
'--list', '-l', action='store_const', dest='format', const='list',
|
||||
help='Shows a list of all migrations and which are applied.',
|
||||
)
|
||||
formats.add_argument(
|
||||
'--plan', '-p', action='store_const', dest='format', const='plan',
|
||||
help='Shows all migrations in the order they will be applied.',
|
||||
)
|
||||
|
||||
parser.set_defaults(format='list')
|
||||
|
||||
|
@ -15,9 +15,10 @@ class Command(BaseCommand):
|
||||
|
||||
def add_arguments(self, parser):
|
||||
super(Command, self).add_arguments(parser)
|
||||
parser.add_argument('--database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to print the SQL for. Defaults to the '
|
||||
'"default" database.')
|
||||
parser.add_argument(
|
||||
'--database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to print the SQL for. Defaults to the "default" database.',
|
||||
)
|
||||
|
||||
def handle(self, **options):
|
||||
return '\n'.join(sql_flush(self.style, connections[options['database']], only_django=True))
|
||||
|
@ -13,15 +13,17 @@ class Command(BaseCommand):
|
||||
output_transaction = True
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('app_label',
|
||||
help='App label of the application containing the migration.')
|
||||
parser.add_argument('migration_name',
|
||||
help='Migration name to print the SQL for.')
|
||||
parser.add_argument('--database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to create SQL for. Defaults to the '
|
||||
'"default" database.')
|
||||
parser.add_argument('--backwards', action='store_true', dest='backwards',
|
||||
default=False, help='Creates SQL to unapply the migration, rather than to apply it')
|
||||
parser.add_argument('app_label', help='App label of the application containing the migration.')
|
||||
parser.add_argument('migration_name', help='Migration name to print the SQL for.')
|
||||
parser.add_argument(
|
||||
'--database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to create SQL for. Defaults to the "default" database.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--backwards', action='store_true', dest='backwards',
|
||||
default=False,
|
||||
help='Creates SQL to unapply the migration, rather than to apply it',
|
||||
)
|
||||
|
||||
def execute(self, *args, **options):
|
||||
# sqlmigrate doesn't support coloring its output but we need to force
|
||||
|
@ -11,9 +11,10 @@ class Command(AppCommand):
|
||||
|
||||
def add_arguments(self, parser):
|
||||
super(Command, self).add_arguments(parser)
|
||||
parser.add_argument('--database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to print the SQL for. Defaults to the '
|
||||
'"default" database.')
|
||||
parser.add_argument(
|
||||
'--database', default=DEFAULT_DB_ALIAS,
|
||||
help='Nominates a database to print the SQL for. Defaults to the "default" database.',
|
||||
)
|
||||
|
||||
def handle_app_config(self, app_config, **options):
|
||||
if app_config.models_module is None:
|
||||
|
@ -13,17 +13,26 @@ class Command(BaseCommand):
|
||||
help = "Squashes an existing set of migrations (from first until specified) into a single new one."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('app_label',
|
||||
help='App label of the application to squash migrations for.')
|
||||
parser.add_argument('start_migration_name', default=None, nargs='?',
|
||||
help='Migrations will be squashed starting from and including this migration.')
|
||||
parser.add_argument('migration_name',
|
||||
help='Migrations will be squashed until and including this migration.')
|
||||
parser.add_argument('--no-optimize', action='store_true', dest='no_optimize', default=False,
|
||||
help='Do not try to optimize the squashed operations.')
|
||||
parser.add_argument('--noinput', '--no-input',
|
||||
action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.')
|
||||
parser.add_argument(
|
||||
'app_label',
|
||||
help='App label of the application to squash migrations for.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'start_migration_name', default=None, nargs='?',
|
||||
help='Migrations will be squashed starting from and including this migration.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'migration_name',
|
||||
help='Migrations will be squashed until and including this migration.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-optimize', action='store_true', dest='no_optimize', default=False,
|
||||
help='Do not try to optimize the squashed operations.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--noinput', '--no-input', action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.',
|
||||
)
|
||||
|
||||
def handle(self, **options):
|
||||
|
||||
|
@ -5,9 +5,10 @@ from django.core.management.templates import TemplateCommand
|
||||
|
||||
|
||||
class Command(TemplateCommand):
|
||||
help = ("Creates a Django app directory structure for the given app "
|
||||
"name in the current directory or optionally in the given "
|
||||
"directory.")
|
||||
help = (
|
||||
"Creates a Django app directory structure for the given app name in "
|
||||
"the current directory or optionally in the given directory."
|
||||
)
|
||||
missing_args_message = "You must provide an application name."
|
||||
|
||||
def handle(self, **options):
|
||||
@ -20,8 +21,9 @@ class Command(TemplateCommand):
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
raise CommandError("%r conflicts with the name of an existing "
|
||||
"Python module and cannot be used as an app "
|
||||
"name. Please try another name." % app_name)
|
||||
raise CommandError(
|
||||
"%r conflicts with the name of an existing Python module and "
|
||||
"cannot be used as an app name. Please try another name." % app_name
|
||||
)
|
||||
|
||||
super(Command, self).handle('app', app_name, target, **options)
|
||||
|
@ -7,9 +7,10 @@ from ..utils import get_random_secret_key
|
||||
|
||||
|
||||
class Command(TemplateCommand):
|
||||
help = ("Creates a Django project directory structure for the given "
|
||||
"project name in the current directory or optionally in the "
|
||||
"given directory.")
|
||||
help = (
|
||||
"Creates a Django project directory structure for the given project "
|
||||
"name in the current directory or optionally in the given directory."
|
||||
)
|
||||
missing_args_message = "You must provide a project name."
|
||||
|
||||
def handle(self, **options):
|
||||
@ -22,10 +23,10 @@ class Command(TemplateCommand):
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
raise CommandError("%r conflicts with the name of an existing "
|
||||
"Python module and cannot be used as a "
|
||||
"project name. Please try another name." %
|
||||
project_name)
|
||||
raise CommandError(
|
||||
"%r conflicts with the name of an existing Python module and "
|
||||
"cannot be used as a project name. Please try another name." % project_name
|
||||
)
|
||||
|
||||
# Create a random SECRET_KEY to put it in the main settings.
|
||||
options['secret_key'] = get_random_secret_key()
|
||||
|
@ -29,24 +29,29 @@ class Command(BaseCommand):
|
||||
super(Command, self).run_from_argv(argv)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('args', metavar='test_label', nargs='*',
|
||||
help='Module paths to test; can be modulename, modulename.TestCase or modulename.TestCase.test_method')
|
||||
parser.add_argument('--noinput', '--no-input',
|
||||
action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.')
|
||||
parser.add_argument('--failfast',
|
||||
action='store_true', dest='failfast', default=False,
|
||||
help='Tells Django to stop running the test suite after first '
|
||||
'failed test.')
|
||||
parser.add_argument('--testrunner',
|
||||
action='store', dest='testrunner',
|
||||
parser.add_argument(
|
||||
'args', metavar='test_label', nargs='*',
|
||||
help='Module paths to test; can be modulename, modulename.TestCase or modulename.TestCase.test_method'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--noinput', '--no-input', action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--failfast', action='store_true', dest='failfast', default=False,
|
||||
help='Tells Django to stop running the test suite after first failed test.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--testrunner', action='store', dest='testrunner',
|
||||
help='Tells Django to use specified test runner class instead of '
|
||||
'the one specified by the TEST_RUNNER setting.')
|
||||
parser.add_argument('--liveserver',
|
||||
action='store', dest='liveserver', default=None,
|
||||
'the one specified by the TEST_RUNNER setting.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--liveserver', action='store', dest='liveserver', default=None,
|
||||
help='Overrides the default address where the live server (used '
|
||||
'with LiveServerTestCase) is expected to run from. The '
|
||||
'default value is localhost:8081-8179.')
|
||||
'default value is localhost:8081-8179.',
|
||||
)
|
||||
|
||||
test_runner_class = get_runner(settings, self.test_runner)
|
||||
|
||||
|
@ -9,15 +9,22 @@ class Command(BaseCommand):
|
||||
requires_system_checks = False
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('args', metavar='fixture', nargs='*',
|
||||
help='Path(s) to fixtures to load before running the server.')
|
||||
parser.add_argument('--noinput', '--no-input',
|
||||
action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.')
|
||||
parser.add_argument('--addrport', default='',
|
||||
help='Port number or ipaddr:port to run the server on.')
|
||||
parser.add_argument('--ipv6', '-6', action='store_true', dest='use_ipv6', default=False,
|
||||
help='Tells Django to use an IPv6 address.')
|
||||
parser.add_argument(
|
||||
'args', metavar='fixture', nargs='*',
|
||||
help='Path(s) to fixtures to load before running the server.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--noinput', '--no-input', action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--addrport', default='',
|
||||
help='Port number or ipaddr:port to run the server on.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--ipv6', '-6', action='store_true', dest='use_ipv6', default=False,
|
||||
help='Tells Django to use an IPv6 address.',
|
||||
)
|
||||
|
||||
def handle(self, *fixture_labels, **options):
|
||||
verbosity = options['verbosity']
|
||||
|
@ -51,18 +51,20 @@ class TemplateCommand(BaseCommand):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('name', help='Name of the application or project.')
|
||||
parser.add_argument('directory', nargs='?', help='Optional destination directory')
|
||||
parser.add_argument('--template',
|
||||
help='The path or URL to load the template from.')
|
||||
parser.add_argument('--extension', '-e', dest='extensions',
|
||||
parser.add_argument('--template', help='The path or URL to load the template from.')
|
||||
parser.add_argument(
|
||||
'--extension', '-e', dest='extensions',
|
||||
action='append', default=['py'],
|
||||
help='The file extension(s) to render (default: "py"). '
|
||||
'Separate multiple extensions with commas, or use '
|
||||
'-e multiple times.')
|
||||
parser.add_argument('--name', '-n', dest='files',
|
||||
'-e multiple times.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--name', '-n', dest='files',
|
||||
action='append', default=[],
|
||||
help='The file name(s) to render. '
|
||||
'Separate multiple extensions with commas, or use '
|
||||
'-n multiple times.')
|
||||
help='The file name(s) to render. Separate multiple extensions '
|
||||
'with commas, or use -n multiple times.'
|
||||
)
|
||||
|
||||
def handle(self, app_or_project, name, target=None, **options):
|
||||
self.app_or_project = app_or_project
|
||||
|
@ -227,9 +227,12 @@ def sort_dependencies(app_list):
|
||||
else:
|
||||
skipped.append((model, deps))
|
||||
if not changed:
|
||||
raise RuntimeError("Can't resolve dependencies for %s in serialized app list." %
|
||||
', '.join('%s.%s' % (model._meta.app_label, model._meta.object_name)
|
||||
for model, deps in sorted(skipped, key=lambda obj: obj[0].__name__))
|
||||
raise RuntimeError(
|
||||
"Can't resolve dependencies for %s in serialized app list." %
|
||||
', '.join(
|
||||
'%s.%s' % (model._meta.app_label, model._meta.object_name)
|
||||
for model, deps in sorted(skipped, key=lambda obj: obj[0].__name__)
|
||||
)
|
||||
)
|
||||
model_dependencies = skipped
|
||||
|
||||
|
@ -75,8 +75,9 @@ class Serializer(base.Serializer):
|
||||
else:
|
||||
def m2m_value(value):
|
||||
return force_text(value._get_pk_val(), strings_only=True)
|
||||
self._current[field.name] = [m2m_value(related)
|
||||
for related in getattr(obj, field.name).iterator()]
|
||||
self._current[field.name] = [
|
||||
m2m_value(related) for related in getattr(obj, field.name).iterator()
|
||||
]
|
||||
|
||||
def getvalue(self):
|
||||
return self.objects
|
||||
|
@ -160,8 +160,7 @@ class Signer(object):
|
||||
'Unsafe Signer separator: %r (cannot be empty or consist of '
|
||||
'only A-z0-9-_=)' % sep,
|
||||
)
|
||||
self.salt = force_str(salt or
|
||||
'%s.%s' % (self.__class__.__module__, self.__class__.__name__))
|
||||
self.salt = force_str(salt or '%s.%s' % (self.__class__.__module__, self.__class__.__name__))
|
||||
|
||||
def signature(self, value):
|
||||
signature = base64_hmac(self.salt + 'signer', value, self.key)
|
||||
|
@ -6,8 +6,7 @@ from django.utils import six
|
||||
TableInfo = namedtuple('TableInfo', ['name', 'type'])
|
||||
|
||||
# Structure returned by the DB-API cursor.description interface (PEP 249)
|
||||
FieldInfo = namedtuple('FieldInfo',
|
||||
'name type_code display_size internal_size precision scale null_ok')
|
||||
FieldInfo = namedtuple('FieldInfo', 'name type_code display_size internal_size precision scale null_ok')
|
||||
|
||||
|
||||
class BaseDatabaseIntrospection(object):
|
||||
|
@ -43,8 +43,8 @@ from .validation import DatabaseValidation # isort:skip
|
||||
# lexicographic ordering in this check because then (1, 2, 1, 'gamma')
|
||||
# inadvertently passes the version test.
|
||||
version = Database.version_info
|
||||
if (version < (1, 2, 1) or (version[:3] == (1, 2, 1) and
|
||||
(len(version) < 5 or version[3] != 'final' or version[4] < 2))):
|
||||
if (version < (1, 2, 1) or (
|
||||
version[:3] == (1, 2, 1) and (len(version) < 5 or version[3] != 'final' or version[4] < 2))):
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
raise ImproperlyConfigured("MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__)
|
||||
|
||||
@ -334,19 +334,27 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
continue
|
||||
key_columns = self.introspection.get_key_columns(cursor, table_name)
|
||||
for column_name, referenced_table_name, referenced_column_name in key_columns:
|
||||
cursor.execute("""
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
|
||||
LEFT JOIN `%s` as REFERRED
|
||||
ON (REFERRING.`%s` = REFERRED.`%s`)
|
||||
WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL"""
|
||||
% (primary_key_column_name, column_name, table_name, referenced_table_name,
|
||||
column_name, referenced_column_name, column_name, referenced_column_name))
|
||||
WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL
|
||||
""" % (
|
||||
primary_key_column_name, column_name, table_name,
|
||||
referenced_table_name, column_name, referenced_column_name,
|
||||
column_name, referenced_column_name,
|
||||
)
|
||||
)
|
||||
for bad_row in cursor.fetchall():
|
||||
raise utils.IntegrityError("The row in table '%s' with primary key '%s' has an invalid "
|
||||
raise utils.IntegrityError(
|
||||
"The row in table '%s' with primary key '%s' has an invalid "
|
||||
"foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s."
|
||||
% (table_name, bad_row[0],
|
||||
table_name, column_name, bad_row[1],
|
||||
referenced_table_name, referenced_column_name))
|
||||
% (
|
||||
table_name, bad_row[0], table_name, column_name,
|
||||
bad_row[1], referenced_table_name, referenced_column_name,
|
||||
)
|
||||
)
|
||||
|
||||
def is_usable(self):
|
||||
try:
|
||||
|
@ -12,7 +12,8 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||
compiler_module = "django.db.backends.mysql.compiler"
|
||||
|
||||
# MySQL stores positive fields as UNSIGNED ints.
|
||||
integer_field_ranges = dict(BaseDatabaseOperations.integer_field_ranges,
|
||||
integer_field_ranges = dict(
|
||||
BaseDatabaseOperations.integer_field_ranges,
|
||||
PositiveSmallIntegerField=(0, 65535),
|
||||
PositiveIntegerField=(0, 4294967295),
|
||||
)
|
||||
|
@ -367,8 +367,7 @@ class OracleParam(object):
|
||||
else:
|
||||
# To transmit to the database, we need Unicode if supported
|
||||
# To get size right, we must consider bytes.
|
||||
self.force_bytes = convert_unicode(param, cursor.charset,
|
||||
strings_only)
|
||||
self.force_bytes = convert_unicode(param, cursor.charset, strings_only)
|
||||
if isinstance(self.force_bytes, six.string_types):
|
||||
# We could optimize by only converting up to 4000 bytes here
|
||||
string_size = len(force_bytes(param, cursor.charset, strings_only))
|
||||
@ -498,8 +497,7 @@ class FormatStylePlaceholderCursor(object):
|
||||
formatted = [firstparams] + [self._format_params(p) for p in params_iter]
|
||||
self._guess_input_sizes(formatted)
|
||||
try:
|
||||
return self.cursor.executemany(query,
|
||||
[self._param_generator(p) for p in formatted])
|
||||
return self.cursor.executemany(query, [self._param_generator(p) for p in formatted])
|
||||
except Database.DatabaseError as e:
|
||||
# cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
|
||||
if hasattr(e.args[0], 'code') and e.args[0].code == 1400 and not isinstance(e, IntegrityError):
|
||||
|
@ -99,8 +99,7 @@ WHEN (new.%(col_name)s IS NULL)
|
||||
days = str(timedelta.days)
|
||||
day_precision = len(days)
|
||||
fmt = "INTERVAL '%s %02d:%02d:%02d.%06d' DAY(%d) TO SECOND(6)"
|
||||
return fmt % (days, hours, minutes, seconds, timedelta.microseconds,
|
||||
day_precision), []
|
||||
return fmt % (days, hours, minutes, seconds, timedelta.microseconds, day_precision), []
|
||||
|
||||
def date_trunc_sql(self, lookup_type, field_name):
|
||||
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm#i1002084
|
||||
|
@ -139,11 +139,11 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||
# This will be the case if it's an m2m using an autogenerated
|
||||
# intermediate table (see BaseDatabaseIntrospection.sequence_list)
|
||||
column_name = 'id'
|
||||
sql.append("%s setval(pg_get_serial_sequence('%s','%s'), 1, false);" %
|
||||
(style.SQL_KEYWORD('SELECT'),
|
||||
sql.append("%s setval(pg_get_serial_sequence('%s','%s'), 1, false);" % (
|
||||
style.SQL_KEYWORD('SELECT'),
|
||||
style.SQL_TABLE(self.quote_name(table_name)),
|
||||
style.SQL_FIELD(column_name))
|
||||
)
|
||||
style.SQL_FIELD(column_name),
|
||||
))
|
||||
return sql
|
||||
|
||||
def tablespace_sql(self, tablespace, inline=False):
|
||||
|
@ -282,18 +282,28 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
continue
|
||||
key_columns = self.introspection.get_key_columns(cursor, table_name)
|
||||
for column_name, referenced_table_name, referenced_column_name in key_columns:
|
||||
cursor.execute("""
|
||||
cursor.execute(
|
||||
"""
|
||||
SELECT REFERRING.`%s`, REFERRING.`%s` FROM `%s` as REFERRING
|
||||
LEFT JOIN `%s` as REFERRED
|
||||
ON (REFERRING.`%s` = REFERRED.`%s`)
|
||||
WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL"""
|
||||
% (primary_key_column_name, column_name, table_name, referenced_table_name,
|
||||
column_name, referenced_column_name, column_name, referenced_column_name))
|
||||
WHERE REFERRING.`%s` IS NOT NULL AND REFERRED.`%s` IS NULL
|
||||
"""
|
||||
% (
|
||||
primary_key_column_name, column_name, table_name,
|
||||
referenced_table_name, column_name, referenced_column_name,
|
||||
column_name, referenced_column_name,
|
||||
)
|
||||
)
|
||||
for bad_row in cursor.fetchall():
|
||||
raise utils.IntegrityError("The row in table '%s' with primary key '%s' has an invalid "
|
||||
"foreign key: %s.%s contains a value '%s' that does not have a corresponding value in %s.%s."
|
||||
% (table_name, bad_row[0], table_name, column_name, bad_row[1],
|
||||
referenced_table_name, referenced_column_name))
|
||||
raise utils.IntegrityError(
|
||||
"The row in table '%s' with primary key '%s' has an "
|
||||
"invalid foreign key: %s.%s contains a value '%s' that "
|
||||
"does not have a corresponding value in %s.%s." % (
|
||||
table_name, bad_row[0], table_name, column_name,
|
||||
bad_row[1], referenced_table_name, referenced_column_name,
|
||||
)
|
||||
)
|
||||
|
||||
def is_usable(self):
|
||||
return True
|
||||
|
@ -85,7 +85,8 @@ class CursorDebugWrapper(CursorWrapper):
|
||||
'sql': sql,
|
||||
'time': "%.3f" % duration,
|
||||
})
|
||||
logger.debug('(%.3f) %s; args=%s', duration, sql, params,
|
||||
logger.debug(
|
||||
'(%.3f) %s; args=%s', duration, sql, params,
|
||||
extra={'duration': duration, 'sql': sql, 'params': params}
|
||||
)
|
||||
|
||||
@ -104,7 +105,8 @@ class CursorDebugWrapper(CursorWrapper):
|
||||
'sql': '%s times: %s' % (times, sql),
|
||||
'time': "%.3f" % duration,
|
||||
})
|
||||
logger.debug('(%.3f) %s; args=%s', duration, sql, param_list,
|
||||
logger.debug(
|
||||
'(%.3f) %s; args=%s', duration, sql, param_list,
|
||||
extra={'duration': duration, 'sql': sql, 'params': param_list}
|
||||
)
|
||||
|
||||
@ -154,9 +156,11 @@ def typecast_timestamp(s): # does NOT store time zone information
|
||||
else:
|
||||
microseconds = '0'
|
||||
tzinfo = utc if settings.USE_TZ else None
|
||||
return datetime.datetime(int(dates[0]), int(dates[1]), int(dates[2]),
|
||||
return datetime.datetime(
|
||||
int(dates[0]), int(dates[1]), int(dates[2]),
|
||||
int(times[0]), int(times[1]), int(seconds),
|
||||
int((microseconds + '000000')[:6]), tzinfo)
|
||||
int((microseconds + '000000')[:6]), tzinfo
|
||||
)
|
||||
|
||||
|
||||
def typecast_decimal(s):
|
||||
|
@ -519,9 +519,10 @@ class Model(six.with_metaclass(ModelBase)):
|
||||
if pickled_version:
|
||||
current_version = get_version()
|
||||
if current_version != pickled_version:
|
||||
msg = ("Pickled model instance's Django version %s does"
|
||||
" not match the current version %s."
|
||||
% (pickled_version, current_version))
|
||||
msg = (
|
||||
"Pickled model instance's Django version %s does not match "
|
||||
"the current version %s." % (pickled_version, current_version)
|
||||
)
|
||||
else:
|
||||
msg = "Pickled model instance's Django version is not specified."
|
||||
|
||||
@ -1285,9 +1286,7 @@ class Model(six.with_metaclass(ModelBase)):
|
||||
@classmethod
|
||||
def _check_id_field(cls):
|
||||
""" Check if `id` field is a primary key. """
|
||||
|
||||
fields = list(f for f in cls._meta.local_fields
|
||||
if f.name == 'id' and f != cls._meta.pk)
|
||||
fields = list(f for f in cls._meta.local_fields if f.name == 'id' and f != cls._meta.pk)
|
||||
# fields is empty or consists of the invalid "id" field
|
||||
if fields and not fields[0].primary_key and cls._meta.pk.name == 'id':
|
||||
return [
|
||||
@ -1342,8 +1341,7 @@ class Model(six.with_metaclass(ModelBase)):
|
||||
# field "id" and automatically added unique field "id", both
|
||||
# defined at the same model. This special case is considered in
|
||||
# _check_id_field and here we ignore it.
|
||||
id_conflict = (f.name == "id" and
|
||||
clash and clash.name == "id" and clash.model == cls)
|
||||
id_conflict = f.name == "id" and clash and clash.name == "id" and clash.model == cls
|
||||
if clash and not id_conflict:
|
||||
errors.append(
|
||||
checks.Error(
|
||||
@ -1397,8 +1395,7 @@ class Model(six.with_metaclass(ModelBase)):
|
||||
)
|
||||
]
|
||||
|
||||
elif any(not isinstance(fields, (tuple, list))
|
||||
for fields in cls._meta.index_together):
|
||||
elif any(not isinstance(fields, (tuple, list)) for fields in cls._meta.index_together):
|
||||
return [
|
||||
checks.Error(
|
||||
"All 'index_together' elements must be lists or tuples.",
|
||||
@ -1425,8 +1422,7 @@ class Model(six.with_metaclass(ModelBase)):
|
||||
)
|
||||
]
|
||||
|
||||
elif any(not isinstance(fields, (tuple, list))
|
||||
for fields in cls._meta.unique_together):
|
||||
elif any(not isinstance(fields, (tuple, list)) for fields in cls._meta.unique_together):
|
||||
return [
|
||||
checks.Error(
|
||||
"All 'unique_together' elements must be lists or tuples.",
|
||||
|
@ -20,8 +20,9 @@ def CASCADE(collector, field, sub_objs, using):
|
||||
|
||||
|
||||
def PROTECT(collector, field, sub_objs, using):
|
||||
raise ProtectedError("Cannot delete some instances of model '%s' because "
|
||||
"they are referenced through a protected foreign key: '%s.%s'" % (
|
||||
raise ProtectedError(
|
||||
"Cannot delete some instances of model '%s' because they are "
|
||||
"referenced through a protected foreign key: '%s.%s'" % (
|
||||
field.remote_field.model.__name__, sub_objs[0].__class__.__name__, field.name
|
||||
),
|
||||
sub_objs
|
||||
@ -165,7 +166,7 @@ class Collector(object):
|
||||
return [objs]
|
||||
|
||||
def collect(self, objs, source=None, nullable=False, collect_related=True,
|
||||
source_attr=None, reverse_dependency=False, keep_parents=False):
|
||||
source_attr=None, reverse_dependency=False, keep_parents=False):
|
||||
"""
|
||||
Adds 'objs' to the collection of objects to be deleted as well as all
|
||||
parent instances. 'objs' must be a homogeneous iterable collection of
|
||||
|
@ -137,12 +137,12 @@ class Field(RegisterLookupMixin):
|
||||
description = property(_description)
|
||||
|
||||
def __init__(self, verbose_name=None, name=None, primary_key=False,
|
||||
max_length=None, unique=False, blank=False, null=False,
|
||||
db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
|
||||
serialize=True, unique_for_date=None, unique_for_month=None,
|
||||
unique_for_year=None, choices=None, help_text='', db_column=None,
|
||||
db_tablespace=None, auto_created=False, validators=[],
|
||||
error_messages=None):
|
||||
max_length=None, unique=False, blank=False, null=False,
|
||||
db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
|
||||
serialize=True, unique_for_date=None, unique_for_month=None,
|
||||
unique_for_year=None, choices=None, help_text='', db_column=None,
|
||||
db_tablespace=None, auto_created=False, validators=[],
|
||||
error_messages=None):
|
||||
self.name = name
|
||||
self.verbose_name = verbose_name # May be set by set_attributes_from_name
|
||||
self._verbose_name = verbose_name # Store original for deconstruction
|
||||
@ -806,8 +806,7 @@ class Field(RegisterLookupMixin):
|
||||
if callable(self.default):
|
||||
return self.default()
|
||||
return self.default
|
||||
if (not self.empty_strings_allowed or (self.null and
|
||||
not connection.features.interprets_empty_strings_as_nulls)):
|
||||
if not self.empty_strings_allowed or self.null and not connection.features.interprets_empty_strings_as_nulls:
|
||||
return None
|
||||
return ""
|
||||
|
||||
@ -1177,10 +1176,8 @@ class DateTimeCheckMixin(object):
|
||||
# auto_now, auto_now_add, and default are mutually exclusive
|
||||
# options. The use of more than one of these options together
|
||||
# will trigger an Error
|
||||
mutually_exclusive_options = [self.auto_now_add, self.auto_now,
|
||||
self.has_default()]
|
||||
enabled_options = [option not in (None, False)
|
||||
for option in mutually_exclusive_options].count(True)
|
||||
mutually_exclusive_options = [self.auto_now_add, self.auto_now, self.has_default()]
|
||||
enabled_options = [option not in (None, False) for option in mutually_exclusive_options].count(True)
|
||||
if enabled_options > 1:
|
||||
return [
|
||||
checks.Error(
|
||||
@ -1314,12 +1311,14 @@ class DateField(DateTimeCheckMixin, Field):
|
||||
def contribute_to_class(self, cls, name, **kwargs):
|
||||
super(DateField, self).contribute_to_class(cls, name, **kwargs)
|
||||
if not self.null:
|
||||
setattr(cls, 'get_next_by_%s' % self.name,
|
||||
curry(cls._get_next_or_previous_by_FIELD, field=self,
|
||||
is_next=True))
|
||||
setattr(cls, 'get_previous_by_%s' % self.name,
|
||||
curry(cls._get_next_or_previous_by_FIELD, field=self,
|
||||
is_next=False))
|
||||
setattr(
|
||||
cls, 'get_next_by_%s' % self.name,
|
||||
curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=True)
|
||||
)
|
||||
setattr(
|
||||
cls, 'get_previous_by_%s' % self.name,
|
||||
curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=False)
|
||||
)
|
||||
|
||||
def get_prep_value(self, value):
|
||||
value = super(DateField, self).get_prep_value(value)
|
||||
@ -1633,8 +1632,7 @@ class DecimalField(Field):
|
||||
return utils.format_number(value, self.max_digits, self.decimal_places)
|
||||
|
||||
def get_db_prep_save(self, value, connection):
|
||||
return connection.ops.adapt_decimalfield_value(self.to_python(value),
|
||||
self.max_digits, self.decimal_places)
|
||||
return connection.ops.adapt_decimalfield_value(self.to_python(value), self.max_digits, self.decimal_places)
|
||||
|
||||
def get_prep_value(self, value):
|
||||
value = super(DecimalField, self).get_prep_value(value)
|
||||
@ -2002,8 +2000,7 @@ class GenericIPAddressField(Field):
|
||||
value = force_text(value)
|
||||
value = value.strip()
|
||||
if ':' in value:
|
||||
return clean_ipv6_address(value,
|
||||
self.unpack_ipv4, self.error_messages['invalid'])
|
||||
return clean_ipv6_address(value, self.unpack_ipv4, self.error_messages['invalid'])
|
||||
return value
|
||||
|
||||
def get_db_prep_value(self, value, connection, prepared=False):
|
||||
|
@ -369,8 +369,7 @@ class ImageField(FileField):
|
||||
descriptor_class = ImageFileDescriptor
|
||||
description = _("Image")
|
||||
|
||||
def __init__(self, verbose_name=None, name=None, width_field=None,
|
||||
height_field=None, **kwargs):
|
||||
def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
|
||||
self.width_field, self.height_field = width_field, height_field
|
||||
super(ImageField, self).__init__(verbose_name, name, **kwargs)
|
||||
|
||||
|
@ -221,8 +221,7 @@ class RelatedField(Field):
|
||||
# model_set and it clashes with Target.model_set.
|
||||
potential_clashes = rel_opts.fields + rel_opts.many_to_many
|
||||
for clash_field in potential_clashes:
|
||||
clash_name = "%s.%s" % (rel_opts.object_name,
|
||||
clash_field.name) # i. e. "Target.model_set"
|
||||
clash_name = "%s.%s" % (rel_opts.object_name, clash_field.name) # i.e. "Target.model_set"
|
||||
if not rel_is_hidden and clash_field.name == rel_name:
|
||||
errors.append(
|
||||
checks.Error(
|
||||
@ -441,8 +440,8 @@ class ForeignObject(RelatedField):
|
||||
rel_class = ForeignObjectRel
|
||||
|
||||
def __init__(self, to, on_delete, from_fields, to_fields, rel=None, related_name=None,
|
||||
related_query_name=None, limit_choices_to=None, parent_link=False,
|
||||
swappable=True, **kwargs):
|
||||
related_query_name=None, limit_choices_to=None, parent_link=False,
|
||||
swappable=True, **kwargs):
|
||||
|
||||
if rel is None:
|
||||
rel = self.rel_class(
|
||||
@ -491,8 +490,9 @@ class ForeignObject(RelatedField):
|
||||
has_unique_constraint = any(u <= foreign_fields for u in unique_foreign_fields)
|
||||
|
||||
if not has_unique_constraint and len(self.foreign_related_fields) > 1:
|
||||
field_combination = ', '.join("'%s'" % rel_field.name
|
||||
for rel_field in self.foreign_related_fields)
|
||||
field_combination = ', '.join(
|
||||
"'%s'" % rel_field.name for rel_field in self.foreign_related_fields
|
||||
)
|
||||
model_name = self.remote_field.model.__name__
|
||||
return [
|
||||
checks.Error(
|
||||
@ -743,8 +743,8 @@ class ForeignKey(ForeignObject):
|
||||
description = _("Foreign Key (type determined by related field)")
|
||||
|
||||
def __init__(self, to, on_delete=None, related_name=None, related_query_name=None,
|
||||
limit_choices_to=None, parent_link=False, to_field=None,
|
||||
db_constraint=True, **kwargs):
|
||||
limit_choices_to=None, parent_link=False, to_field=None,
|
||||
db_constraint=True, **kwargs):
|
||||
try:
|
||||
to._meta.model_name
|
||||
except AttributeError:
|
||||
@ -1111,9 +1111,9 @@ class ManyToManyField(RelatedField):
|
||||
description = _("Many-to-many relationship")
|
||||
|
||||
def __init__(self, to, related_name=None, related_query_name=None,
|
||||
limit_choices_to=None, symmetrical=None, through=None,
|
||||
through_fields=None, db_constraint=True, db_table=None,
|
||||
swappable=True, **kwargs):
|
||||
limit_choices_to=None, symmetrical=None, through=None,
|
||||
through_fields=None, db_constraint=True, db_table=None,
|
||||
swappable=True, **kwargs):
|
||||
try:
|
||||
to._meta
|
||||
except AttributeError:
|
||||
@ -1241,8 +1241,10 @@ class ManyToManyField(RelatedField):
|
||||
|
||||
# Count foreign keys in intermediate model
|
||||
if self_referential:
|
||||
seen_self = sum(from_model == getattr(field.remote_field, 'model', None)
|
||||
for field in self.remote_field.through._meta.fields)
|
||||
seen_self = sum(
|
||||
from_model == getattr(field.remote_field, 'model', None)
|
||||
for field in self.remote_field.through._meta.fields
|
||||
)
|
||||
|
||||
if seen_self > 2 and not self.remote_field.through_fields:
|
||||
errors.append(
|
||||
@ -1260,10 +1262,14 @@ class ManyToManyField(RelatedField):
|
||||
|
||||
else:
|
||||
# Count foreign keys in relationship model
|
||||
seen_from = sum(from_model == getattr(field.remote_field, 'model', None)
|
||||
for field in self.remote_field.through._meta.fields)
|
||||
seen_to = sum(to_model == getattr(field.remote_field, 'model', None)
|
||||
for field in self.remote_field.through._meta.fields)
|
||||
seen_from = sum(
|
||||
from_model == getattr(field.remote_field, 'model', None)
|
||||
for field in self.remote_field.through._meta.fields
|
||||
)
|
||||
seen_to = sum(
|
||||
to_model == getattr(field.remote_field, 'model', None)
|
||||
for field in self.remote_field.through._meta.fields
|
||||
)
|
||||
|
||||
if seen_from > 1 and not self.remote_field.through_fields:
|
||||
errors.append(
|
||||
@ -1469,8 +1475,7 @@ class ManyToManyField(RelatedField):
|
||||
elif self.db_table:
|
||||
return self.db_table
|
||||
else:
|
||||
return utils.truncate_name('%s_%s' % (opts.db_table, self.name),
|
||||
connection.ops.max_name_length())
|
||||
return utils.truncate_name('%s_%s' % (opts.db_table, self.name), connection.ops.max_name_length())
|
||||
|
||||
def _get_m2m_attr(self, related, attr):
|
||||
"""
|
||||
|
@ -868,16 +868,19 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||
def clear(self):
|
||||
db = router.db_for_write(self.through, instance=self.instance)
|
||||
with transaction.atomic(using=db, savepoint=False):
|
||||
signals.m2m_changed.send(sender=self.through, action="pre_clear",
|
||||
signals.m2m_changed.send(
|
||||
sender=self.through, action="pre_clear",
|
||||
instance=self.instance, reverse=self.reverse,
|
||||
model=self.model, pk_set=None, using=db)
|
||||
|
||||
model=self.model, pk_set=None, using=db,
|
||||
)
|
||||
filters = self._build_remove_filters(super(ManyRelatedManager, self).get_queryset().using(db))
|
||||
self.through._default_manager.using(db).filter(filters).delete()
|
||||
|
||||
signals.m2m_changed.send(sender=self.through, action="post_clear",
|
||||
signals.m2m_changed.send(
|
||||
sender=self.through, action="post_clear",
|
||||
instance=self.instance, reverse=self.reverse,
|
||||
model=self.model, pk_set=None, using=db)
|
||||
model=self.model, pk_set=None, using=db,
|
||||
)
|
||||
clear.alters_data = True
|
||||
|
||||
def set(self, objs, **kwargs):
|
||||
@ -905,9 +908,10 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||
|
||||
new_objs = []
|
||||
for obj in objs:
|
||||
fk_val = (self.target_field.get_foreign_related_value(obj)[0]
|
||||
if isinstance(obj, self.model) else obj)
|
||||
|
||||
fk_val = (
|
||||
self.target_field.get_foreign_related_value(obj)[0]
|
||||
if isinstance(obj, self.model) else obj
|
||||
)
|
||||
if fk_val in old_ids:
|
||||
old_ids.remove(fk_val)
|
||||
else:
|
||||
@ -998,9 +1002,11 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||
if self.reverse or source_field_name == self.source_field_name:
|
||||
# Don't send the signal when we are inserting the
|
||||
# duplicate data row for symmetrical reverse entries.
|
||||
signals.m2m_changed.send(sender=self.through, action='pre_add',
|
||||
signals.m2m_changed.send(
|
||||
sender=self.through, action='pre_add',
|
||||
instance=self.instance, reverse=self.reverse,
|
||||
model=self.model, pk_set=new_ids, using=db)
|
||||
model=self.model, pk_set=new_ids, using=db,
|
||||
)
|
||||
|
||||
# Add the ones that aren't there already
|
||||
self.through._default_manager.using(db).bulk_create([
|
||||
@ -1014,9 +1020,11 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||
if self.reverse or source_field_name == self.source_field_name:
|
||||
# Don't send the signal when we are inserting the
|
||||
# duplicate data row for symmetrical reverse entries.
|
||||
signals.m2m_changed.send(sender=self.through, action='post_add',
|
||||
signals.m2m_changed.send(
|
||||
sender=self.through, action='post_add',
|
||||
instance=self.instance, reverse=self.reverse,
|
||||
model=self.model, pk_set=new_ids, using=db)
|
||||
model=self.model, pk_set=new_ids, using=db,
|
||||
)
|
||||
|
||||
def _remove_items(self, source_field_name, target_field_name, *objs):
|
||||
# source_field_name: the PK colname in join table for the source object
|
||||
@ -1037,9 +1045,11 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||
db = router.db_for_write(self.through, instance=self.instance)
|
||||
with transaction.atomic(using=db, savepoint=False):
|
||||
# Send a signal to the other end if need be.
|
||||
signals.m2m_changed.send(sender=self.through, action="pre_remove",
|
||||
signals.m2m_changed.send(
|
||||
sender=self.through, action="pre_remove",
|
||||
instance=self.instance, reverse=self.reverse,
|
||||
model=self.model, pk_set=old_ids, using=db)
|
||||
model=self.model, pk_set=old_ids, using=db,
|
||||
)
|
||||
target_model_qs = super(ManyRelatedManager, self).get_queryset()
|
||||
if target_model_qs._has_filters():
|
||||
old_vals = target_model_qs.using(db).filter(**{
|
||||
@ -1049,8 +1059,10 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
|
||||
filters = self._build_remove_filters(old_vals)
|
||||
self.through._default_manager.using(db).filter(filters).delete()
|
||||
|
||||
signals.m2m_changed.send(sender=self.through, action="post_remove",
|
||||
signals.m2m_changed.send(
|
||||
sender=self.through, action="post_remove",
|
||||
instance=self.instance, reverse=self.reverse,
|
||||
model=self.model, pk_set=old_ids, using=db)
|
||||
model=self.model, pk_set=old_ids, using=db,
|
||||
)
|
||||
|
||||
return ManyRelatedManager
|
||||
|
@ -40,7 +40,7 @@ class ForeignObjectRel(object):
|
||||
null = True
|
||||
|
||||
def __init__(self, field, to, related_name=None, related_query_name=None,
|
||||
limit_choices_to=None, parent_link=False, on_delete=None):
|
||||
limit_choices_to=None, parent_link=False, on_delete=None):
|
||||
self.field = field
|
||||
self.model = to
|
||||
self.related_name = related_name
|
||||
@ -212,7 +212,7 @@ class ManyToOneRel(ForeignObjectRel):
|
||||
"""
|
||||
|
||||
def __init__(self, field, to, field_name, related_name=None, related_query_name=None,
|
||||
limit_choices_to=None, parent_link=False, on_delete=None):
|
||||
limit_choices_to=None, parent_link=False, on_delete=None):
|
||||
super(ManyToOneRel, self).__init__(
|
||||
field, to,
|
||||
related_name=related_name,
|
||||
@ -235,8 +235,7 @@ class ManyToOneRel(ForeignObjectRel):
|
||||
"""
|
||||
field = self.model._meta.get_field(self.field_name)
|
||||
if not field.concrete:
|
||||
raise exceptions.FieldDoesNotExist("No related field named '%s'" %
|
||||
self.field_name)
|
||||
raise exceptions.FieldDoesNotExist("No related field named '%s'" % self.field_name)
|
||||
return field
|
||||
|
||||
def set_field_name(self):
|
||||
@ -252,7 +251,7 @@ class OneToOneRel(ManyToOneRel):
|
||||
"""
|
||||
|
||||
def __init__(self, field, to, field_name, related_name=None, related_query_name=None,
|
||||
limit_choices_to=None, parent_link=False, on_delete=None):
|
||||
limit_choices_to=None, parent_link=False, on_delete=None):
|
||||
super(OneToOneRel, self).__init__(
|
||||
field, to, field_name,
|
||||
related_name=related_name,
|
||||
@ -274,8 +273,8 @@ class ManyToManyRel(ForeignObjectRel):
|
||||
"""
|
||||
|
||||
def __init__(self, field, to, related_name=None, related_query_name=None,
|
||||
limit_choices_to=None, symmetrical=True, through=None, through_fields=None,
|
||||
db_constraint=True):
|
||||
limit_choices_to=None, symmetrical=True, through=None,
|
||||
through_fields=None, db_constraint=True):
|
||||
super(ManyToManyRel, self).__init__(
|
||||
field, to,
|
||||
related_name=related_name,
|
||||
|
@ -28,13 +28,14 @@ IMMUTABLE_WARNING = (
|
||||
"for your own use, make a copy first."
|
||||
)
|
||||
|
||||
DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering',
|
||||
'unique_together', 'permissions', 'get_latest_by',
|
||||
'order_with_respect_to', 'app_label', 'db_tablespace',
|
||||
'abstract', 'managed', 'proxy', 'swappable', 'auto_created',
|
||||
'index_together', 'apps', 'default_permissions',
|
||||
'select_on_save', 'default_related_name',
|
||||
'required_db_features', 'required_db_vendor')
|
||||
DEFAULT_NAMES = (
|
||||
'verbose_name', 'verbose_name_plural', 'db_table', 'ordering',
|
||||
'unique_together', 'permissions', 'get_latest_by', 'order_with_respect_to',
|
||||
'app_label', 'db_tablespace', 'abstract', 'managed', 'proxy', 'swappable',
|
||||
'auto_created', 'index_together', 'apps', 'default_permissions',
|
||||
'select_on_save', 'default_related_name', 'required_db_features',
|
||||
'required_db_vendor',
|
||||
)
|
||||
|
||||
|
||||
def normalize_together(option_together):
|
||||
@ -249,8 +250,7 @@ class Options(object):
|
||||
field.primary_key = True
|
||||
self.setup_pk(field)
|
||||
else:
|
||||
auto = AutoField(verbose_name='ID', primary_key=True,
|
||||
auto_created=True)
|
||||
auto = AutoField(verbose_name='ID', primary_key=True, auto_created=True)
|
||||
model.add_to_class('id', auto)
|
||||
|
||||
def add_field(self, field, virtual=False):
|
||||
@ -385,8 +385,7 @@ class Options(object):
|
||||
return make_immutable_fields_list(
|
||||
"fields",
|
||||
(f for f in self._get_fields(reverse=False)
|
||||
if is_not_an_m2m_field(f) and is_not_a_generic_relation(f) and
|
||||
is_not_a_generic_foreign_key(f))
|
||||
if is_not_an_m2m_field(f) and is_not_a_generic_relation(f) and is_not_a_generic_foreign_key(f))
|
||||
)
|
||||
|
||||
@cached_property
|
||||
@ -426,8 +425,7 @@ class Options(object):
|
||||
"""
|
||||
return make_immutable_fields_list(
|
||||
"many_to_many",
|
||||
(f for f in self._get_fields(reverse=False)
|
||||
if f.is_relation and f.many_to_many)
|
||||
(f for f in self._get_fields(reverse=False) if f.is_relation and f.many_to_many)
|
||||
)
|
||||
|
||||
@cached_property
|
||||
@ -444,8 +442,7 @@ class Options(object):
|
||||
all_related_fields = self._get_fields(forward=False, reverse=True, include_hidden=True)
|
||||
return make_immutable_fields_list(
|
||||
"related_objects",
|
||||
(obj for obj in all_related_fields
|
||||
if not obj.hidden or obj.field.many_to_many)
|
||||
(obj for obj in all_related_fields if not obj.hidden or obj.field.many_to_many)
|
||||
)
|
||||
|
||||
@cached_property
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user