Vraag Haal modelvelden in Django


Met een Django-model probeer ik alle velden op te sommen. Ik heb hier enkele voorbeelden van gezien met behulp van het attribuut _meta-model, maar geeft het onderstrepingsteken voor de meta niet aan dat het attribuut _meta een privéattribuut is en niet direct moet worden benaderd? ... Omdat de lay-out van _meta bijvoorbeeld in de toekomst kan veranderen en geen stabiele API is?

Is _meta een uitzondering op deze regel? Is het stabiel en klaar voor gebruik of wordt het als een slechte gewoonte beschouwd om er toegang toe te hebben? Of is er een functie of een andere manier om de velden van een model te verkennen zonder het attribuut _meta te gebruiken? Hieronder is een lijst met enkele koppelingen die laten zien hoe dit te doen met behulp van het _meta attribuut

Elk advies wordt zeer op prijs gesteld.

django object get / set veld

http://www.djangofoo.com/80/get-list-model-fields

Hoe django modelvelden te verkennen?


89
2017-09-05 21:06


oorsprong


antwoorden:


_meta is privé, maar het is relatief stabiel. Er zijn inspanningen om het te formaliseren, te documenteren en het onderstrepingsteken te verwijderen, wat kan gebeuren vóór 1.3 of 1.4. Ik stel me voor dat alles in het werk wordt gesteld om ervoor te zorgen dat dingen achterwaarts compatibel zijn, omdat veel mensen het toch al hebben gebruikt.

Als je je vooral zorgen maakt over compatibiliteit, schrijf dan een functie die een model nodig heeft en de velden retourneert. Dit betekent dat als er in de toekomst iets verandert, u slechts één functie hoeft te wijzigen.

def get_model_fields(model):
    return model._meta.fields

Ik geloof dat dit een lijst zal teruggeven van Field voorwerpen. Gebruik de waarde van elk veld uit de instantie getattr(instance, field.name).

Update: Django-bijdragers werken aan een API om het _Meta-object te vervangen als onderdeel van een Google Summer of Code. Zien:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api


122
2017-09-05 21:44



Ik weet dat dit bericht vrij oud is, maar ik wilde het iedereen vertellen die op zoek is naar hetzelfde dat er een openbare en officiële API is om dit te doen: get_fields() en get_field()

Gebruik:

fields = model._meta.get_fields()
my_field = model._meta.get_field('my_field')

https://docs.djangoproject.com/en/1.8/ref/models/meta/


66
2018-04-02 23:07



Dit is iets dat door Django zelf gedaan wordt bij het bouwen van een formulier uit een model. Het gebruikt het attribuut _meta, maar zoals Bernhard opmerkte, gebruikt het zowel _meta.fields als _meta.many_to_many. Kijkend naar django.forms.models.fields_for_model, dit is hoe je het zou kunnen doen:

opts = model._meta
for f in sorted(opts.fields + opts.many_to_many):
    print '%s: %s' % (f.name, f)

8
2018-01-16 18:58



De modelvelden van _meta worden op meerdere locaties weergegeven als lijsten van de respectieve veldobjecten. Het is misschien gemakkelijker om ermee te werken als een woordenboek waarbij de toetsen de veldnamen zijn.

Dit is naar mijn mening de meest irredundante en expressieve manier om de modelveldobjecten te verzamelen en te ordenen:

def get_model_fields(model):
  fields = {}
  options = model._meta
  for field in sorted(options.concrete_fields + options.many_to_many + options.virtual_fields):
    fields[field.name] = field
  return fields

(Zien Dit voorbeeld gebruik in django.forms.models.fields_for_model.)


4
2017-12-08 21:39



Nu is er een speciale methode - get_fields ()

    >>> from django.contrib.auth.models import User
    >>> User._meta.get_fields()

Het accepteert twee parameters die kunnen worden gebruikt om te bepalen welke velden worden geretourneerd:

  • include_parents

    Waar standaard. Recursief omvat velden die zijn gedefinieerd in bovenliggende klassen. Indien ingesteld op False, zoekt get_fields () alleen naar velden die direct op het huidige model zijn gedeclareerd. Velden van modellen die direct erven van abstracte modellen of proxyklassen worden beschouwd als lokaal, niet als ouder.

  • include_hidden

    Standaard false. Indien ingesteld op True, zal get_fields () velden bevatten die worden gebruikt om de functionaliteit van een ander veld te ondersteunen. Dit omvat ook alle velden met een related_name (zoals ManyToManyField of ForeignKey) die beginnen met een "+"


3
2017-12-01 06:13



Wat dacht je van deze.

fields = Model._meta.fields

1
2017-08-03 15:31



get_fields() geeft a terug tuple en elk element is een Model field type, dat niet direct als een tekenreeks kan worden gebruikt. Zo, field.name geeft de veldnaam terug

my_model_fields = [field.name for field in MyModel._meta.get_fields()]
De bovenstaande code retourneert een lijst die de naam van alle velden bevat

Voorbeeld

In [11]: from django.contrib.auth.models import User

In [12]: User._meta.get_fields()
Out[12]: 
(<ManyToOneRel: admin.logentry>,
 <django.db.models.fields.AutoField: id>,
 <django.db.models.fields.CharField: password>,
 <django.db.models.fields.DateTimeField: last_login>,
 <django.db.models.fields.BooleanField: is_superuser>,
 <django.db.models.fields.CharField: username>,
 <django.db.models.fields.CharField: first_name>,
 <django.db.models.fields.CharField: last_name>,
 <django.db.models.fields.EmailField: email>,
 <django.db.models.fields.BooleanField: is_staff>,
 <django.db.models.fields.BooleanField: is_active>,
 <django.db.models.fields.DateTimeField: date_joined>,
 <django.db.models.fields.related.ManyToManyField: groups>,
 <django.db.models.fields.related.ManyToManyField: user_permissions>)

In [13]: [field.name for field in User._meta.get_fields()]
Out[13]: 
['logentry',
 'id',
 'password',
 'last_login',
 'is_superuser',
 'username',
 'first_name',
 'last_name',
 'email',
 'is_staff',
 'is_active',
 'date_joined',
 'groups',
 'user_permissions']

0
2017-07-31 06:29