我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用django.db.models.ManyToManyField()。
def _check_raw_id_fields_item(self, obj, model, field_name, label): """ Check an item of `raw_id_fields`, i.e. check that field named `field_name` exists in model `model` and is a ForeignKey or a ManyToManyField. """ try: field = model._meta.get_field(field_name) except FieldDoesNotExist: return refer_to_missing_field(field=field_name, option=label, model=model, obj=obj, id='admin.E002') else: if not isinstance(field, (models.ForeignKey, models.ManyToManyField)): return must_be('a ForeignKey or ManyToManyField', option=label, obj=obj, id='admin.E003') else: return []
def get_field_style(self, attrs, db_field, style, **kwargs): if style == 'm2m_transfer' and isinstance(db_field, ManyToManyField): return {'widget': widgets.SelectMultipleTransfer(db_field.verbose_name, False), 'help_text': ''} if style == 'm2m_dropdown' and isinstance(db_field, ManyToManyField): return {'widget': widgets.SelectMultipleDropdown, 'help_text': ''} if style == 'm2m_select' and isinstance(db_field, ManyToManyField): return {'widget': widgets.AdminSelectMultiple} if style == 'm2m_raw' and isinstance(db_field, ManyToManyField): db = kwargs.get('using') return {'widget': widgets.ManyToManyRawIdWidget(db_field.rel, self.admin_view, using=db), 'help_text': ''} if style == 'm2m_ajax' and isinstance(db_field, ManyToManyField): return {'widget': widgets.SelectMultipleAjax(db_field.rel, self.admin_view,False), 'help_text': ''} if style == 'm2m_ajax_multi' and isinstance(db_field, ManyToManyField): return {'widget': widgets.SelectMultipleAjax(db_field.rel, self.admin_view,True), 'help_text': ''} if style == 'm2m_select2' and isinstance(db_field, ManyToManyField): return {'widget': widgets.SelectMultipleDropselect, 'help_text': ''} return attrs
def _check_ignored_options(self, **kwargs): warnings = [] if self.has_null_arg: warnings.append( checks.Warning( 'null has no effect on ManyToManyField.', hint=None, obj=self, id='fields.W340', ) ) if len(self._validators) > 0: warnings.append( checks.Warning( 'ManyToManyField does not support validators.', hint=None, obj=self, id='fields.W341', ) ) return warnings
def contribute_to_class(self, cls, name, **kwargs): # To support multiple relations to self, it's useful to have a non-None # related name on symmetrical relations for internal reasons. The # concept doesn't make a lot of sense externally ("you want me to # specify *what* on my non-reversible relation?!"), so we set it up # automatically. The funky name reduces the chance of an accidental # clash. if self.remote_field.symmetrical and ( self.remote_field.model == "self" or self.remote_field.model == cls._meta.object_name): self.remote_field.related_name = "%s_rel_+" % name elif self.remote_field.is_hidden(): # If the backwards relation is disabled, replace the original # related_name with one generated from the m2m field name. Django # still uses backwards relations internally and we need to avoid # clashes between multiple m2m fields with related_name == '+'. self.remote_field.related_name = "_%s_%s_+" % (cls.__name__.lower(), name) super(ManyToManyField, self).contribute_to_class(cls, name, **kwargs) # The intermediate m2m model is not auto created if: # 1) There is a manually specified intermediate, or # 2) The class owning the m2m field is abstract. # 3) The class owning the m2m field has been swapped out. if not cls._meta.abstract: if self.remote_field.through: def resolve_through_model(_, model, field): field.remote_field.through = model lazy_related_operation(resolve_through_model, cls, self.remote_field.through, field=self) elif not cls._meta.swapped: self.remote_field.through = create_many_to_many_intermediary_model(self, cls) # Add the descriptor for the m2m relation. setattr(cls, self.name, ManyToManyDescriptor(self.remote_field, reverse=False)) # Set up the accessor for the m2m table name for the relation. self.m2m_db_table = curry(self._get_m2m_db_table, cls._meta)
def _check_raw_id_fields_item(self, obj, model, field_name, label): """ Check an item of `raw_id_fields`, i.e. check that field named `field_name` exists in model `model` and is a ForeignKey or a ManyToManyField. """ try: field = model._meta.get_field(field_name) except FieldDoesNotExist: return refer_to_missing_field(field=field_name, option=label, model=model, obj=obj, id='admin.E002') else: if not field.many_to_many and not isinstance(field, models.ForeignKey): return must_be('a foreign key or a many-to-many field', option=label, obj=obj, id='admin.E003') else: return []
def _check_prepopulated_fields_key(self, obj, model, field_name, label): """ Check a key of `prepopulated_fields` dictionary, i.e. check that it is a name of existing field and the field is one of the allowed types. """ try: field = model._meta.get_field(field_name) except FieldDoesNotExist: return refer_to_missing_field(field=field_name, option=label, model=model, obj=obj, id='admin.E027') else: if isinstance(field, (models.DateTimeField, models.ForeignKey, models.ManyToManyField)): return [ checks.Error( "The value of '%s' refers to '%s', which must not be a DateTimeField, " "a ForeignKey, or a ManyToManyField." % (label, field_name), obj=obj.__class__, id='admin.E028', ) ] else: return []
def _check_prepopulated_fields_key(self, obj, model, field_name, label): """ Check a key of `prepopulated_fields` dictionary, i.e. check that it is a name of existing field and the field is one of the allowed types. """ try: field = model._meta.get_field(field_name) except FieldDoesNotExist: return refer_to_missing_field(field=field_name, option=label, model=model, obj=obj, id='admin.E027') else: if isinstance(field, (models.DateTimeField, models.ForeignKey, models.ManyToManyField)): return [ checks.Error( "The value of '%s' refers to '%s', which must not be a DateTimeField, " "a ForeignKey, a OneToOneField, or a ManyToManyField." % (label, field_name), obj=obj.__class__, id='admin.E028', ) ] else: return []
def validate_prepopulated_fields(self, cls, model): " Validate that prepopulated_fields if a dictionary containing allowed field types. " # prepopulated_fields if hasattr(cls, 'prepopulated_fields'): check_isdict(cls, 'prepopulated_fields', cls.prepopulated_fields) for field, val in cls.prepopulated_fields.items(): f = get_field(cls, model, 'prepopulated_fields', field) if isinstance(f, (models.DateTimeField, models.ForeignKey, models.ManyToManyField)): raise ImproperlyConfigured("'%s.prepopulated_fields['%s']' " "is either a DateTimeField, ForeignKey or " "ManyToManyField. This isn't allowed." % (cls.__name__, field)) check_isseq(cls, "prepopulated_fields['%s']" % field, val) for idx, f in enumerate(val): get_field(cls, model, "prepopulated_fields['%s'][%d]" % (field, idx), f)
def validate_list_display(self, cls, model): " Validate that list_display only contains fields or usable attributes. " if hasattr(cls, 'list_display'): check_isseq(cls, 'list_display', cls.list_display) for idx, field in enumerate(cls.list_display): if not callable(field): if not hasattr(cls, field): if not hasattr(model, field): try: model._meta.get_field(field) except FieldDoesNotExist: raise ImproperlyConfigured( "%s.list_display[%d], %r is not a callable or " "an attribute of %r or found in the model %r." % (cls.__name__, idx, field, cls.__name__, model._meta.object_name) ) else: # getattr(model, field) could be an X_RelatedObjectsDescriptor f = fetch_attr(cls, model, "list_display[%d]" % idx, field) if isinstance(f, models.ManyToManyField): raise ImproperlyConfigured( "'%s.list_display[%d]', '%s' is a ManyToManyField " "which is not supported." % (cls.__name__, idx, field) )
def _check_raw_id_fields_item(self, cls, model, field_name, label): """ Check an item of `raw_id_fields`, i.e. check that field named `field_name` exists in model `model` and is a ForeignKey or a ManyToManyField. """ try: field = model._meta.get_field(field_name) except FieldDoesNotExist: return refer_to_missing_field(field=field_name, option=label, model=model, obj=cls, id='admin.E002') else: if not isinstance(field, (models.ForeignKey, models.ManyToManyField)): return must_be('a ForeignKey or ManyToManyField', option=label, obj=cls, id='admin.E003') else: return []
def get_field_docs(self, fieldname): try: field = self.model._meta.get_field(fieldname) if isinstance(field, models.ForeignKey): return _serializers[field.rel.to].docs() elif isinstance(field, models.ManyToManyField): spec = _serializers[field.rel.to].docs() spec['array'] = True return spec elif isinstance(field, models.ManyToOneRel): spec = _serializers[field.related_model].docs() spec['array'] = True return spec return FieldDocs(self.model, field) except models.FieldDoesNotExist: model = getattr(self.model, fieldname).related.related_model spec = _serializers[model].docs() spec['array'] = True return spec
def accessible_courses(self): # If the user has access to a 'parent object', i.e. the related # semester, then we grant access to all children parent_access = Q(semesters__in=self.accessible_semesters()) # Also includes courses where the contributor is part of the contributors ManyToManyField, # which the user is added to if he/she created the course earlier_contributor = Q(contributors__in=[self]) access_criterion = parent_access | earlier_contributor # If the user has recently taken the course, according to dataporten, # we grant access. Here, recently means either the current semester, # or the last one if isinstance(self.user, DataportenUser): recent_course = Q(course_code__in=self.user.dataporten.courses.less_semesters_ago(than=2)) access_criterion = access_criterion | recent_course return Course.objects.filter(access_criterion).distinct()
def get_form_datas(self): """ ? Request ??? Form ?????? """ if self.request_method == 'get': initial = dict(self.request.GET.items()) for k in initial: try: f = self.opts.get_field(k) except models.FieldDoesNotExist: continue if isinstance(f, models.ManyToManyField): # ????????????????? initial[k] = initial[k].split(",") return {'initial': initial} else: return {'data': self.request.POST, 'files': self.request.FILES}
def _showfields_get_content(self, field_name, field_type=type(None)): "helper for __unicode__" content = getattr(self, field_name) if self.polymorphic_showfield_old_format: out = ': ' else: out = ' ' if issubclass(field_type, models.ForeignKey): if content is None: out += 'None' else: out += content.__class__.__name__ elif issubclass(field_type, models.ManyToManyField): out += '%d' % content.count() elif isinstance(content, six.integer_types): out += str(content) elif content is None: out += 'None' else: txt = str(content) if len(txt) > self.polymorphic_showfield_max_field_width: txt = txt[:self.polymorphic_showfield_max_field_width - 2] + '..' out += '"' + txt + '"' return out
def _is_m2m(user_field): field = FeatureFlipper._meta.get_field(user_field) return isinstance(field, ManyToManyField)
def __enter__(self): self._old_au_local_m2m = AbstractUser._meta.local_many_to_many self._old_pm_local_m2m = PermissionsMixin._meta.local_many_to_many groups = models.ManyToManyField(Group, blank=True) groups.contribute_to_class(PermissionsMixin, "groups") user_permissions = models.ManyToManyField(Permission, blank=True) user_permissions.contribute_to_class(PermissionsMixin, "user_permissions") PermissionsMixin._meta.local_many_to_many = [groups, user_permissions] AbstractUser._meta.local_many_to_many = [groups, user_permissions]
def _check_field_name(self): field_name = self._get_field_name() try: field = self.model._meta.get_field(field_name) except FieldDoesNotExist: return [ checks.Error( "CurrentSiteManager could not find a field named '%s'." % field_name, hint=None, obj=self, id='sites.E001', ) ] if not isinstance(field, (models.ForeignKey, models.ManyToManyField)): return [ checks.Error( "CurrentSiteManager cannot use '%s.%s' as it is not a ForeignKey or ManyToManyField." % ( self.model._meta.object_name, field_name ), hint=None, obj=self, id='sites.E002', ) ] return []
def _check_field_spec_item(self, obj, model, field_name, label): if field_name in obj.readonly_fields: # Stuff can be put in fields that isn't actually a model field if # it's in readonly_fields, readonly_fields will handle the # validation of such things. return [] else: try: field = model._meta.get_field(field_name) except FieldDoesNotExist: # If we can't find a field on the model that matches, it could # be an extra field on the form. return [] else: if (isinstance(field, models.ManyToManyField) and not field.remote_field.through._meta.auto_created): return [ checks.Error( ("The value of '%s' cannot include the ManyToManyField '%s', " "because that field manually specifies a relationship model.") % (label, field_name), hint=None, obj=obj.__class__, id='admin.E013', ) ] else: return []
def _check_filter_item(self, obj, model, field_name, label): """ Check one item of `filter_vertical` or `filter_horizontal`, i.e. check that given field exists and is a ManyToManyField. """ try: field = model._meta.get_field(field_name) except FieldDoesNotExist: return refer_to_missing_field(field=field_name, option=label, model=model, obj=obj, id='admin.E019') else: if not isinstance(field, models.ManyToManyField): return must_be('a ManyToManyField', option=label, obj=obj, id='admin.E020') else: return []
def formfield_for_manytomany(self, db_field, request=None, **kwargs): """ Get a form Field for a ManyToManyField. """ # If it uses an intermediary model that isn't auto created, don't show # a field in admin. if not db_field.remote_field.through._meta.auto_created: return None 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['help_text'] = '' elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)): kwargs['widget'] = widgets.FilteredSelectMultiple( db_field.verbose_name, db_field.name in self.filter_vertical ) if 'queryset' not in kwargs: queryset = self.get_field_queryset(db, db_field, request) if queryset is not None: kwargs['queryset'] = queryset form_field = db_field.formfield(**kwargs) if isinstance(form_field.widget, SelectMultiple) and not isinstance(form_field.widget, CheckboxSelectMultiple): msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.') help_text = form_field.help_text form_field.help_text = string_concat(help_text, ' ', msg) if help_text else msg return form_field
def get_changeform_initial_data(self, request): """ Get the initial form data. Unless overridden, this populates from the GET params. """ initial = dict(request.GET.items()) for k in initial: try: f = self.model._meta.get_field(k) except FieldDoesNotExist: continue # We have to special-case M2Ms as a list of comma-separated PKs. if isinstance(f, models.ManyToManyField): initial[k] = initial[k].split(",") return initial
def _generate_added_field(self, app_label, model_name, field_name): field = self.new_apps.get_model(app_label, model_name)._meta.get_field(field_name) # Fields that are foreignkeys/m2ms depend on stuff dependencies = [] if field.remote_field and field.remote_field.model: # Account for FKs to swappable models swappable_setting = getattr(field, 'swappable_setting', None) if swappable_setting is not None: dep_app_label = "__setting__" dep_object_name = swappable_setting else: dep_app_label = field.remote_field.model._meta.app_label dep_object_name = field.remote_field.model._meta.object_name dependencies = [(dep_app_label, dep_object_name, None, True)] if getattr(field.remote_field, "through", None) and not field.remote_field.through._meta.auto_created: dependencies.append(( field.remote_field.through._meta.app_label, field.remote_field.through._meta.object_name, None, True, )) # You can't just add NOT NULL fields with no default or fields # which don't allow empty strings as default. preserve_default = True if (not field.null and not field.has_default() and not isinstance(field, models.ManyToManyField) and not (field.blank and field.empty_strings_allowed)): field = field.clone() field.default = self.questioner.ask_not_null_addition(field_name, model_name) preserve_default = False self.add_operation( app_label, operations.AddField( model_name=model_name, name=field_name, field=field, preserve_default=preserve_default, ), dependencies=dependencies, )
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): try: to._meta except AttributeError: assert isinstance(to, six.string_types), ( "%s(%r) is invalid. First parameter to ManyToManyField must be " "either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT) ) # Class names must be ASCII in Python 2.x, so we forcibly coerce it # here to break early if there's a problem. to = str(to) if symmetrical is None: symmetrical = (to == RECURSIVE_RELATIONSHIP_CONSTANT) if through is not None: assert db_table is None, ( "Cannot specify a db_table if an intermediary model is used." ) kwargs['rel'] = self.rel_class( self, to, related_name=related_name, related_query_name=related_query_name, limit_choices_to=limit_choices_to, symmetrical=symmetrical, through=through, through_fields=through_fields, db_constraint=db_constraint, ) self.has_null_arg = 'null' in kwargs super(ManyToManyField, self).__init__(**kwargs) self.db_table = db_table self.swappable = swappable
def check(self, **kwargs): errors = super(ManyToManyField, self).check(**kwargs) errors.extend(self._check_unique(**kwargs)) errors.extend(self._check_relationship_model(**kwargs)) errors.extend(self._check_ignored_options(**kwargs)) return errors
def db_type(self, connection): # A ManyToManyField is not represented by a single column, # so return None. return None
def _check_field_spec_item(self, obj, model, field_name, label): if field_name in obj.readonly_fields: # Stuff can be put in fields that isn't actually a model field if # it's in readonly_fields, readonly_fields will handle the # validation of such things. return [] else: try: field = model._meta.get_field(field_name) except FieldDoesNotExist: # If we can't find a field on the model that matches, it could # be an extra field on the form. return [] else: if (isinstance(field, models.ManyToManyField) and not field.remote_field.through._meta.auto_created): return [ checks.Error( "The value of '%s' cannot include the ManyToManyField '%s', " "because that field manually specifies a relationship model." % (label, field_name), obj=obj.__class__, id='admin.E013', ) ] else: return []
def _check_filter_item(self, obj, model, field_name, label): """ Check one item of `filter_vertical` or `filter_horizontal`, i.e. check that given field exists and is a ManyToManyField. """ try: field = model._meta.get_field(field_name) except FieldDoesNotExist: return refer_to_missing_field(field=field_name, option=label, model=model, obj=obj, id='admin.E019') else: if not field.many_to_many: return must_be('a many-to-many field', option=label, obj=obj, id='admin.E020') else: return []
def formfield_for_manytomany(self, db_field, request, **kwargs): """ Get a form Field for a ManyToManyField. """ # If it uses an intermediary model that isn't auto created, don't show # a field in admin. if not db_field.remote_field.through._meta.auto_created: return None 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) elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)): kwargs['widget'] = widgets.FilteredSelectMultiple( db_field.verbose_name, db_field.name in self.filter_vertical ) if 'queryset' not in kwargs: queryset = self.get_field_queryset(db, db_field, request) if queryset is not None: kwargs['queryset'] = queryset form_field = db_field.formfield(**kwargs) if isinstance(form_field.widget, SelectMultiple) and not isinstance(form_field.widget, CheckboxSelectMultiple): msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.') help_text = form_field.help_text form_field.help_text = string_concat(help_text, ' ', msg) if help_text else msg return form_field
def formfield_for_dbfield(self, db_field, **kwargs): # If it uses an intermediary model that isn't auto created, don't show # a field in admin. if isinstance(db_field, models.ManyToManyField) and not db_field.rel.through._meta.auto_created: return None attrs = self.get_field_attrs(db_field, **kwargs) return db_field.formfield(**dict(attrs, **kwargs))
def get_field_style(self, db_field, style, **kwargs): if style in ('radio', 'radio-inline') and (db_field.choices or isinstance(db_field, models.ForeignKey)): attrs = {'widget': widgets.AdminRadioSelect( attrs={'inline': 'inline' if style == 'radio-inline' else ''})} if db_field.choices: attrs['choices'] = db_field.get_choices( include_blank=db_field.blank, blank_choice=[('', _('Null'))] ) return attrs if style in ('checkbox', 'checkbox-inline') and isinstance(db_field, models.ManyToManyField): return {'widget': widgets.AdminCheckboxSelect(attrs={'inline': style == 'checkbox-inline'}), 'help_text': None}