2010-04-12 5 views
6

Un error extraño aquí, tal vez alguien puede ayudar a rastrear el código fuente ya que intenta extender el proyecto Django CMS & intenta utilizar algunas lógicas escritas como parte de ese proyecto que no estoy totalmente claro sobre en resumen, el uso de:.La vista de lista genérica plantea el error de atributo: el objeto 'función' no tiene el atributo '_clone'

urls.py 
====================== 
from django.conf.urls.defaults import * 
from cmsplugin_flat_news.models import News 

'''RETURNING _CLONE ERROR WHEN IMPLEMENTED 
def get_news(): 
    return News.published.all() 

news_dict = { 
    'queryset': get_news, 
} 

news_list_dic = { 
    'queryset': get_news, 
    'paginate_by': 50, 
} 
''' 
# NEXT SECTION FUNCTIONS BUT NEEDS SERVER RESTART TO SEE NEW POSTS. 
#CHANGING TO JUST News.published.all RAISES SAME ISSUE AS USING WRAPPER 
#SOLUTION ABOVE. SEE: http://docs.djangoproject.com/en/dev/topics/db/queries/#caching-and-querysets 
#& EXAMPLE HERE: http://docs.djangoproject.com/en/dev/topics/generic-views/#adding-extra-context 

news_dict = { 
    'queryset': News.published.all(), 
} 

news_list_dic = { 
    'queryset': News.published.all(),#SAME ISSUE 
    'paginate_by': 50, 
} 

urlpatterns = patterns('django.views.generic.list_detail', 
    (r'^$', 'object_list', news_list_dic), 
    (r'^(?P<page>[0-9]+)/$', 'object_list', dict(news_list_dic)), 
    url(r'^(?P<slug>[-\w]+)/$', 'object_detail', news_dict, name='news_view'), 
) 

models.py 
====================== 
class PublishedNewsManager(models.Manager): 
    #Filters out all unpublished news and news with a publication date in the future 
    def get_query_set(self): 
     return super(PublishedNewsManager, self).get_query_set() \ 
        .filter(is_published=True) \ 
        .filter(pub_date__lte=datetime.datetime.now()) 

class News(models.Model): 
    title   = models.CharField(_('Title'), max_length=255) 
    slug   = models.SlugField(_('Slug'), unique_for_date='pub_date') 
    author   = models.ForeignKey(User) 
    description  = models.TextField(_('Description'), blank=True) 
    image   = generic.GenericRelation('NewsImage', blank=True, null=True) 
    content   = models.TextField(_('Content'), blank=True) 
    tags   = TagField() 
    is_published = models.BooleanField(_('Published'), default=False) 
    pub_date  = models.DateTimeField(_('Publication date'), default=datetime.datetime.now()) 
    created   = models.DateTimeField(auto_now_add=True, editable=False) 
    updated   = models.DateTimeField(auto_now=True, editable=False) 
    published  = PublishedNewsManager() 
    objects   = models.Manager() 

Ver cuestión en los comentarios: básicamente, error generado por la implementación de la solución 'correcta' para agregar contexto extra para las vistas. El error es Attribute Error: "'function' object has no attribute '_clone'"

Probar: News.published.all en lugar de News.published.all() provoca el error w hether se usa como parte de una función de contenedor o directamente en la parte de conjunto de consulta del urlpattern.

¿Falta algo obvio? Creo que tiene que ver con que el PublishedNewsManager no devuelve objetos como un diccionario, o modifica el código para devolver los objetos correctamente a la vista.

Respuesta

9

Los _clone errores son una cortina de humo causada por el que pasa una función como argumento para una visión genérica donde se espera una QuerySet. La versión del código que pasa News.published.all() a las vistas genéricas es correcta, ya que las vistas genéricas intentarán clonar el QuerySet que se les da, para evitar almacenar en caché el primer lote de datos que consultan (de ahí el error al pasar una función) .

Su problema parece ser que su método personalizado get_query_set devuelve un QuerySet filtrada en base a la fecha y hora en que fue llamado el método actual.

no puedo ver nada en la documentación sobre filter argumentos siendo exigible, pero encontré this ticket which suggests that filter can take callable arguments, por lo que trate de cambiar su gestor de pasar en la función de ser llamado para obtener la fecha/hora actual, en lugar de llamarlo inmediatamente:

class PublishedNewsManager(models.Manager): 
    def get_query_set(self): 
     return super(PublishedNewsManager, self).get_query_set() \ 
        .filter(is_published=True) \ 
        .filter(pub_date__lte=datetime.datetime.now) 
+0

Gracias insin, eso es sólo el billete! – Chris

0

Bueno, no es exactamente en el mismo caso de uso como el PO, pero yo estaba tratando de pasar una RawQuerySet a las vistas genéricas y conseguir el error _clone, que me fijo con un truco feo a la instancia de RawQuerySet.

Parece que lo único que quiere hacer la vista genérica es clonar el conjunto de preguntas (¿para el almacenamiento en caché?), Así que hice que el objeto devolviera una copia que satisfacía la llamada a _clone.

de error: Objeto de

'RawQuerySet' no tiene atributo '_clone'

código:

from django.views.generic.list_detail import object_list 

.... 

li_file = File.objects.raw("SELECT * FROM file_file WHERE fn like %s", [search]) 

#adding this fixed the _clone missing error 
def clone(self): 
    #return self - this works as well. 
    return copy.copy(self) 

li_file.__class__._clone = clone 
#end of addition 

return object_list(request, 
       queryset = li_file, 
       template_name = "file/found.html", 
       )   
Cuestiones relacionadas