2016-04-09 3 views
0

Ce que je suis:Comment accéder à l'attribut d'objet à l'aide ManyRelatedManager MPTT

class Category(MPTTModel): 
    name = models.CharField(max_length=50, unique=True) 
    slug = models.SlugField(unique=True) 
    full_slug = models.CharField(max_length=256, null=True, blank=True) 
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True) 

class Work(models.Model): 
    title = models.CharField(max_length=128, unique=True) 
    slug = models.SlugField(max_length=128, unique=True)  
    category = TreeManyToManyField(Category, verbose_name='parent category', related_name='works') 
    url = models.CharField(max_length=256, null=True, blank=True) 

    def save(self, *args, **kwargs): 
     if self.category: 
      self.url = '%s/%s' % (self.category.full_slug, self.slug) 
     else: 
      self.url = '%s' % self.slug 
     super(Work, self).save(*args, **kwargs) 

Mais je reçois une erreur « objet « ManyRelatedManager » n'a pas d'attribut « full_slug » ». En fait, j'ai besoin d'une seule catégorie, donc j'ai essayé self.url = '%s/%s' % (self.category.all()[0].full_slug, self.slug), mais j'ai l'erreur quand même.

Alors, y a-t-il un moyen de résoudre ce problème? La seule façon que je le faire fonctionner est avec category=TreeForeignKey, mais je besoin d'un TreeManyToManyField

Traceback:

Environment: 


Request Method: POST 
Request URL: http://127.0.0.1:8000/admin/website/work/1/change/ 

Django Version: 1.9.5 
Python Version: 3.5.1 
Installed Applications: 
['django.contrib.admin', 
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'mptt', 
'django_mptt_admin', 
'website'] 
Installed Middleware: 
['django.middleware.security.SecurityMiddleware', 
'django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.common.CommonMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware', 
'django.middleware.clickjacking.XFrameOptionsMiddleware'] 



Traceback: 

File "E:\web\env\lib\site-packages\django\core\handlers\base.py" in get_response 
    149.      response = self.process_exception_by_middleware(e, request) 

File "E:\web\env\lib\site-packages\django\core\handlers\base.py" in get_response 
    147.      response = wrapped_callback(request, *callback_args, **callback_kwargs) 

File "E:\web\env\lib\site-packages\django\contrib\admin\options.py" in wrapper 
    541.     return self.admin_site.admin_view(view)(*args, **kwargs) 

File "E:\web\env\lib\site-packages\django\utils\decorators.py" in _wrapped_view 
    149.      response = view_func(request, *args, **kwargs) 

File "E:\web\env\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func 
    57.   response = view_func(request, *args, **kwargs) 

File "E:\web\env\lib\site-packages\django\contrib\admin\sites.py" in inner 
    244.    return view(request, *args, **kwargs) 

File "E:\web\env\lib\site-packages\django\contrib\admin\options.py" in change_view 
    1440.   return self.changeform_view(request, object_id, form_url, extra_context) 

File "E:\web\env\lib\site-packages\django\utils\decorators.py" in _wrapper 
    67.    return bound_func(*args, **kwargs) 

File "E:\web\env\lib\site-packages\django\utils\decorators.py" in _wrapped_view 
    149.      response = view_func(request, *args, **kwargs) 

File "E:\web\env\lib\site-packages\django\utils\decorators.py" in bound_func 
    63.     return func.__get__(self, type(self))(*args2, **kwargs2) 

File "C:\Python35\Lib\contextlib.py" in inner 
    30.     return func(*args, **kwds) 

File "E:\web\env\lib\site-packages\django\contrib\admin\options.py" in changeform_view 
    1378.     self.save_model(request, new_object, form, not add) 

File "E:\web\env\lib\site-packages\django\contrib\admin\options.py" in save_model 
    991.   obj.save() 

File "E:\web\website\models.py" in save 
    63.    self.url = '%s/%s' % (self.category.full_slug, self.slug) 

Exception Type: AttributeError at /admin/website/work/1/change/ 
Exception Value: 'ManyRelatedManager' object has no attribute 'full_slug' 

Répondre

0

En termes simples, vous obtenez cette erreur parce que si vous regardez votre code

category = TreeManyToManyField(Category, verbose_name='parent category', related_name='works') 

Son un many-to-many-field Donc ici def enregistrer (auto, * args, ** kwargs): si auto.catégorie: self.url = '% s /% s'% (auto.catégorie .full_slug, self.slug)

vous dites me donner category.full_slug

Et django vous dit poliment qu'il peut y avoir plusieurs catégories pour et travail par exemple.

C'est donc à vous de déterminer quelle instance de self.category vous voulez.

par exemple.

self.category.first().full_slug 

En savoir plus ici: https://docs.djangoproject.com/en/1.9/ref/models/relations/

Bien sûr self.category.first() ne peut exister que si vous n'avez pas des instances de catégorie qui sont liés à l'instance de travail que vous essayez d'enregistrer. Sur une note très similaire, vous devez d'abord enregistrer l'instance Work avant d'associer des modèles m2m à votre instance Work.