any idea for get_absolute_url in m2m categories

80 views
Skip to first unread message

carlos

unread,
Feb 20, 2017, 12:02:32 AM2/20/17
to django...@googlegroups.com
Hi, any idea how to construct my get_absolute_url (127.0.0.1:8000/category-slug/id-slug-post)
for example i have my models like this
class Category(...):
    name = CharField(....)
    slug = SlugField(.....)

class MyModel(modesl.Model):
    post = models.CharField(....)
    slug = models.SlugField(.....)
    categories = models.ManyToMany(Category)

   def get_absolute_url(self):
       return "/%s/%s-%s/" % (self.categories.slug, self.id, self.slug)

  #error 'ManyRelatedManager' object has no attribute 'slug' 
  in self.categories.slug


i would like this url in my page

example
          domain.com / category slug   / pk - (dash) post slug

the problems is for my get_absolute_url  see, one post have multiple category
the error is:
'ManyRelatedManager' object has no attribute 'slug'

what is the best way to do this?

any idea?

Cheers

--
att.
Carlos Rocha

Mike Dewhirst

unread,
Feb 20, 2017, 12:38:29 AM2/20/17
to django...@googlegroups.com
On 20/02/2017 4:00 PM, carlos wrote:
> Hi, any idea how to construct my get_absolute_url
> (127.0.0.1:8000/category-slug/id-slug-post
> <http://127.0.0.1:8000/category-slug/id-slug-post>)
> for example i have my models like this
> class Category(...):
> name = CharField(....)
> slug = SlugField(.....)
>
> class MyModel(modesl.Model):
> post = models.CharField(....)
> slug = models.SlugField(.....)
> categories = models.ManyToMany(Category)
>
> def get_absolute_url(self):
> return "/%s/%s-%s/" % (self.categories.slug, self.id
> <http://self.id>, self.slug)
>
> #error 'ManyRelatedManager' object has no attribute 'slug'
> in self.categories.slug

https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.ManyToManyField

https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.ManyToManyField.through

The "through" table doesn't need a coded Django model if it is only used
to relate the two different tables in the m2m relationship. However, if
you want to include other data - such as a slug - then you need to code
it explicitly.

The "through" table will already exist in your database so choose the
same name for the model as you see there. It will only have two foreign
key fields, one to each of the related tables after which it is named.

Once you have a model with the two FKs and your slug,
makemigrations/migrate will adjust it to include the slug.


>
>
> i would like this url in my page
> 127.0.0.1:8000/category-slug/id-slug-post
> <http://127.0.0.1:8000/category-slug/id-slug-post>
>
> example
> http://mydomain.com/food-green/120-one-hundry-food-green
> domain.com <http://domain.com> / category slug / pk - (dash) post slug
>
> the problems is for my get_absolute_url see, one post have multiple
> category
> the error is:
> 'ManyRelatedManager' object has no attribute 'slug'
>
> what is the best way to do this?
>
> any idea?
>
> Cheers
>
> --
> att.
> Carlos Rocha
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to django-users...@googlegroups.com
> <mailto:django-users...@googlegroups.com>.
> To post to this group, send email to django...@googlegroups.com
> <mailto:django...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/django-users.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/CAM-7rO0wbik3zq5Tj_Fc9dhQNASnLd%2Bx5mA4Xp%3DAzkKyPS%2BQtg%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-users/CAM-7rO0wbik3zq5Tj_Fc9dhQNASnLd%2Bx5mA4Xp%3DAzkKyPS%2BQtg%40mail.gmail.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.

Melvyn Sopacua

unread,
Feb 20, 2017, 6:07:03 AM2/20/17
to django...@googlegroups.com

On Sunday 19 February 2017 23:00:54 carlos wrote:

 

> class Category(...):

> name = CharField(....)

> slug = SlugField(.....)

>

> class MyModel(modesl.Model):

> post = models.CharField(....)

> slug = models.SlugField(.....)

> categories = models.ManyToMany(Category)

>

> def get_absolute_url(self):

> return "/%s/%s-%s/" % (self.categories.slug, self.id,

> self.slug)

 

Since this is many, this will never work, since you can have more then one category. You have to decide which category is the preferred one or just use the first one that comes up.

 

> #error 'ManyRelatedManager' object has no attribute 'slug'

 

Because the related manager is not a model. With a foreign key (many to one) the remote side is always one, so Django links the ForeignKey with a model instance.

With a ManyToMany relationship, the remote side can be more than one, so the RelatedManager is a ModelManager (for all intents and purposes a QuerySet).

 

The quick and dirty way:

def get_absolute_url(self):

return '/%s/%s-%s/' % (self.categories.first().slug, self.id, self.slug)

 

(Of course, this still is probably incorrect, since this doesn't contain the app prefix).

 

--

Melvyn Sopacua

carlos

unread,
Feb 20, 2017, 9:40:25 AM2/20/17
to django...@googlegroups.com
Hi, Melvyn yes i use similar but for the question is
the best way?

def get_absolute_url(self):

return '/%s/%s-%s/' % (self.categories.all()[0].slug, self.id, self.slug) #this way a take first category, but other best way to do that?


thank for helps :)



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
att.
Carlos Rocha

Melvyn Sopacua

unread,
Feb 20, 2017, 10:25:35 AM2/20/17
to django...@googlegroups.com

On Monday 20 February 2017 08:39:07 carlos wrote:

> Hi, Melvyn yes i use similar but for the question is

> the best way?

>

> def get_absolute_url(self):

>

> return '/%s/%s-%s/' % (self.categories.all()[0].slug, self.id,

> self.slug) #this way a take first category, but other best way to do

> that?

 

Sure. Whatever "the best" may be.

 

Best = "Make sure we always get the same category":

 

class CategoryInfo(models.Model):

my_model = models.ForeignKey('MyModel', on_delete=models.CASCADE, releated_name='+')

category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='+')

is_primary = models.BooleanField(default=False)

 

class MyModel(models.Model):

post = models.CharField(....)

slug = models.SlugField(.....)

categories = models.ManyToMany(Category, through=CategoryInfo)

 

def get_absolute_url(self):

try:

category = CategoryInfo.objects.get(my_model=self, is_primary=True)

except Category.DoesNotExist:

category = CategoryInfo.objects.filter(

my_model=self

).first()

return "/%s/%s-%s/" % (category.slug, self.id, self.slug)

 

Best = "Don't depend on URL structure":

 

class MyModel(models.Model):

# .... fields ....

 

def get_absolute_url(self):

category = self.categories.first()

kwargs = {

'category_slug': category.slug,

'pk': self.pk,

'slug': self.slug,

}

return reverse('mymodel_detail', args=(), kwargs=kwargs)

 

urls.py:

urlpatterns = (

url(

'^(?P<category_slug>[a-z0-9-A-Z_-]+)/(?<pk>[0-9]+)-(?P<slug>[a-z0-9-A-Z_-]+)/$',

views.MyModelDetailView.as_view(),

name='mymodel_detail'

),

)

 

--

Melvyn Sopacua

carlos

unread,
Feb 20, 2017, 11:14:44 PM2/20/17
to django...@googlegroups.com
thank Melvyn :) i understands right now!

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

For more options, visit https://groups.google.com/d/optout.



--
att.
Carlos Rocha
Reply all
Reply to author
Forward
0 new messages