update transaction raw queryset query queries django django-managers django-orm

django - transaction - ¿Cómo usar el administrador personalizado con objetos relacionados?



orm django queries (4)

Tengo un administrador personalizado. Quiero usarlo para objetos relacionados. Encontré use_for_related_fields en docs. Pero no funciona como lo usé:

class RandomQueryset(models.query.QuerySet): def randomize(self): count = self.count() random_index = random.randint(0, count - 1) return self.all()[random_index] class RandomManager(models.Manager): use_for_related_fields = True def get_query_set(self): return RandomQueryset(self.model, using=self._db) def randomize(self): return self.get_query_set().randomize()

Lo utilicé para un modelo:

>>> post = PostPages.default_manager.filter(image_gallery__isnull=False).distinct().randomize()

Y trató de hacer lo mismo con el objeto relacionado m2m:

>>> post.image_gallery.randomize()

Tengo un error

AttributeError: ''ManyRelatedManager'' object has no attribute ''randomize''

¿Es posible usar un administrador personalizado de la forma en que lo hice? Si es así, ¿cómo lo haces funcionar?

Editar

Mis modelos:

class ShivaImage(models.Model, ImageResizing): image = models.ImageField(upload_to=''img'') slide_show = models.BooleanField() title = models.CharField(max_length=100) text = models.TextField(max_length=400) ordering = models.IntegerField(blank=True, null=True) objects = RandomManager() class PostPages(models.Model): image_gallery = models.ManyToManyField(ShivaImage, blank=True, related_name=''gallery'',) # all the other fields... objects = RandomManager()


Además, en el administrador personalizado, asegúrese de acceder al queryset a través del método proxy self.get_query_set () cuando implemente filtros personalizados para llamar desde el administrador relacionado:

class EventManager(models.Manager): use_for_related_fields = True def visible_events(self): today = datetime.date.today() # don''t do this !!! # unsuitable for related managers as could retrieve extraneous objects # qs = super(EventManager, self).get_query_set() # Use queryset proxy method as follows, instead: qs = self.get_query_set() qs = qs.filter(visible_from__lte=today, visible_to__gte=today) return qs class Event(models.Model): visible_from = models.DateField(_(u''visible from''), null=False, blank=False) visible_to = models.DateField(_(u''visible to''), null=False, blank=False) concepts = models.ManyToManyField(Concept, through=''ConceptEventRegistration'') objects = EventManager()

Uso de la muestra:

my_concept = Concept.objects.get(id=1) # retrieve all events related to the object my_concept.event_set.all() # retrieve all visible events related to the object my_concept.event_set.visible_events()


Al establecer use_for_related_fields en True en el administrador, estará disponible en todas las relaciones que apuntan al modelo en el que definió este administrador como el administrador predeterminado. Esto está documentado here

class MyManager(models.Manager): use_for_related_fields = True # ...

Supongo que solo lo tiene activado en su modelo de PostPages , no en su modelo de Gallery (o como se llame el modelo al que se hace referencia a través de post_image_gallery ). Si desea tener una funcionalidad adicional en este administrador de realidades, debe agregar un administrador predeterminado personalizado con use_for_related_fields = True para su modelo de Gallery !


En django 2.0 use_for_related_fields está obsoleto https://docs.djangoproject.com/en/2.0/releases/1.10/#manager-use-for-related-fields-and-inheritance-changes

Debería usar base_manager_name : https://docs.djangoproject.com/en/2.0/ref/models/options/#django.db.models.Options.base_manager_name

Documentos actualizados: https://docs.djangoproject.com/en/2.0/topics/db/managers/#using-managers-for-related-object-access

class MyModel(models.Model): field1 = ... field2 = ... special_manager = MyManager() class Meta: base_manager_name = ''special_manager''


Para completar el tema, Django 1.7 (finalmente) admite el uso de un administrador inverso personalizado , por lo que puede hacer algo como eso (solo copiando desde los documentos de django):

from django.db import models class Entry(models.Model): objects = models.Manager() # Default Manager entries = EntryManager() # Custom Manager b = Blog.objects.get(id=1) b.entry_set(manager=''entries'').all()