Class meta got invalid attributes - django

Please help to fix this Meta class value as I gave up after detailed research.
I am getting back error while trying to handle template urls with "get_absolute_url" as it responds with following error.
TypeError: 'class Meta' got invalid attribute(s): sale_price,get_absolute_url.
Below is my code.
class Meta:
db_table = 'products'
ordering = ['-created_at']
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('catalog_product', (), {'product_slug': self.slug})
def sale_price(self):
if self.old_price > self.price:
return self.price
else:
return None
Thanks.

You are misunderstanding how models are defined. You add your methods and attributes to the actual Model class and use the Meta class to specify options upon the class:
class MyModel(models.Model):
old_price = ...
price = ...
slug = ...
created_at = ...
...
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('catalog_product', (), {'product_slug': self.slug})
def sale_price(self):
if self.old_price > self.price:
return self.price
else:
return None
class Meta:
db_table = 'products'
ordering = ['-created_at']
Have a read of the Model documentation and pay attention to the section on Meta options
EDIT
Also, don't use the permalink decorator as it's no longer recommended:
https://docs.djangoproject.com/en/1.6/ref/models/instances/#the-permalink-decorator
The permalink decorator is no longer recommended. You should use reverse() in the body of your get_absolute_url method instead.

Related

Django get_absolute_url() doesn't seem to work in comment section

I'm trying to get my users to the article page after comments, but something is missing.
class Comment(models.Model):
post = models.ForeignKey(Post, related_name="comments" ,on_delete=models.CASCADE)
name = models.CharField(max_length=30)
body = RichTextUploadingField(extra_plugins=
['youtube', 'codesnippet'], external_plugin_resources= [('youtube','/static/ckeditor/youtube/','plugin.js'), ('codesnippet','/static/ckeditor/codesnippet/','plugin.js')])
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s' % (self.post.title, self.name)
class Meta:
verbose_name = "comentario"
verbose_name_plural = "comentarios"
ordering = ['date_added']
def get_absolute_url(self):
return reverse('article-detail', kwargs={'pk': self.pk})
urls.py
path('article/<int:pk>/comment/', AddCommentView.as_view(), name='add_comment'),
path('article/<int:pk>', ArticleDetailView.as_view(), name="article-detail"),
path('article/edit/<int:pk>', UpdatePostView.as_view(), name='update_post'),
path('article/<int:pk>/remove', DeletePostView.as_view(), name='delete_post'),
For the update_post the get_absolute_url() works. Thanks in advance.
You would need to pass a parameter which belongs to the ArticleDetailView model. For example if the model for the ArticleDetailView is Post:
class ArticleDetailView(DetailView):
model = Post
The get_absolute_url should use a post.pk:
class Comment(models.Model):
....
....
def get_absolute_url(self):
return reverse('article-detail', kwargs={'pk': self.post.pk})
In your case it is not working as it is using the Comment pk with the Article(Post) view
Ok the thing is I was using this class for comment, had to delete the function of success_url and now works.
class AddCommentView(CreateView):
model = Comment
form_class = CommentForm
#form_class = PostForm
template_name = 'add_comment.html'
success_url = reverse_lazy('home')
def form_valid(self,form):
form.instance.post_id = self.kwargs['pk']
return super().form_valid(form)

How can I make Django slug and id work together?

I want my URL to contain both id and slug like StackOverflow, but the slug is not working properly. Instead of being like this:
www.example.com/games/155/far-cry-5
the URL is like this:
www.example.com/games/155/<bound%20method%20Game.slug%20of%20<Game:%20Far%20Cry%205>>
My models.py :
class Game(models.Model):
name = models.CharField(max_length=140)
def slug(self):
return slugify(self.name)
def get_absolute_url(self):
return reverse('core:gamedetail', kwargs={'pk': self.id, 'slug': self.slug})
My views.py :
class GameDetail(DetailView):
model = Game
template_name = 'core/game_detail.html'
context_object_name = 'game_detail'
My urls.py :
path('<int:pk>/<slug>', views.GameDetail.as_view(), name='gamedetail')
Call the slug() method to get the value.
return reverse('core:gamedetail', kwargs={'pk': self.id, 'slug': self.slug()})
Or define it as a propery of the class
#property
def slug(self):
...

Django Slug Not Working In get_absolute_url

Whats wrong with this code? get_absolute_url is blank when rendered in my template, which means It's failing somewhere.
I suspect it's the slug as this is the first time I have tried to use it within Django:
Thanks
Model:
class Entry(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=255, unique=True)
def get_absolute_url(self):
return reverse("EntryDetail", kwargs={"slug": self.slug})
URL:
url(r'^entry/(?P<slug>[^\.]+).html',
blog_views.EntryDetail.as_view(),
name='blog_entry'),
View:
class EntryDetail(DetailView):
context_object_name = 'entry'
template_name = "blog.entry.html"
slug_field = 'slug'
def get_object(self):
return get_object_or_404(Entry, url=self.slug_field)
Based on what #Peter DeGlopper stated in comments: It looks like your trying to get the absolute URL using a Class Based View. Don't use reverse here, instead you should always give your URLs a name, and then refer to that.
For example this is how it should look:
model
#models.permalink
def get_absolute_url(self):
return 'blog_entry', (), {'slug': self.slug}
urls
url(r'^entry/(?P<slug>[^\.]+).html',
blog_views.EntryDetail.as_view(),
name='blog_entry'),

How do I write a write a view in django that gets an object_list based on a field?

I have a simple tag model and a simple project model.
In the project model I have a m2m to the tag model.
I want to return all the projects with a tag. I'm almost there.
Right now the view below returns invalid literal for int() with base 10: 'cheap'
So, it has the right slug, and it's making the query, but it's trying to get the list of projects based on the id of the m2m tag.
Any suggestion much appreciated.
My Tag Model:
class Tag(models.Model):
"""
A basic tag model for projects
"""
name = models.CharField(max_length=100, unique=True)
slug = models.CharField(max_length=100)
description = models.TextField(blank=True)
class Meta:
ordering = ('name',)
verbose_name = _('Tag')
verbose_name_plural = _('Tags')
def __unicode__(self):
return self.name
#models.permalink
def get_url_path(self):
return ('TagDetail', (), {'slug': self.slug})
My url:
# tags/<slug>/ The detail view for an archived project
url(regex=r'^tags/(?P<slug>[\w-]+)/$',
view=TagDetail.as_view(),
name='tag_detail',
),
My view I'm trying to figure out:
class TagDetail(ListView):
""" Get all projects for a tag """
template_name = "projects/TagDetail.html"
def get_queryset(self):
tags = get_list_or_404(Project, tags=self.kwargs['slug'], displayed=True)
paginate_by = 10
#method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(TagDetail, self).dispatch(*args, **kwargs)
Assuming your Project model looks like this
class Project( models.Model ):
tags=models.ManyToManyField( Tag )
match to the tag's slug
def get_queryset( self ):
return get_list_or_404(Project, tags__slug=self.kwargs['slug'], displayed=True)
the only change being tags__slug.

Accessing SubClassed User Profile Module in Django 1.3

I am trying to create two user types in django 1.3. I am subclassing the AUTH_PROFILE_MODULE with the following models.py:
class Member(models.Model):
ROLE_CHOICES = (
(0, 'Guide'),
(1, 'Operator'),
)
user = models.ForeignKey(User, unique=True)
location = models.CharField(max_length=60)
role = models.IntegerField(choices=ROLE_CHOICES)
class Guide(Member):
bio = models.TextField(blank=True)
experience = models.TextField(blank=True)
image = models.ImageField(blank=True, upload_to='images')
fileupload = models.FileField(blank=True, upload_to='files')
def __unicode__(self):
return self.user.username
def get_absolute_url(self):
return '/profiles/guides/%s' % self.user.username
class Operator(Member):
bio = models.TextField(blank=True)
image = models.ImageField(blank=True, upload_to='images')
def __unicode__(self):
return self.user.username
def get_absolute_url(self):
return '/profiles/operators/%s' % self.user.username
I am using generic class based views and can get the ListView to work for the Guide and Operator models I cannot get the DetailView to work. My views.py is as follows:
class GuideDetailView(DetailView):
model = Guide
context_object_name = 'guide'
template_name = 'members/guide_detail.html'
class GuideListView(ListView):
model = Guide
context_object_name = 'guides'
template_name = 'members/guide_list.html'
Any idea what might be missing?
Either provide a queryset:
class GuideDetailView(DetailView):
queryset = Guide.objects.all()
or override the get Method of DetailView:
class GuideDetailView(DetailView):
def get(self):
return "Everything you want, maybe: Guide.object.get(id=1)"
Given this in your urls.py:
url(r'^(?P<my_id>\d)/$', GuideDetailView.as_view(),),
You need to override get, like this:
class GuideDetailView(DetailView):
def get(self, request, **kwargs):
# lookup Guide Id in your database and assign it object
self.object = Guide.objects.get(pk=kwargs.get('my_id'))
# add object to your context_data, so that you can access via your template
context = self.get_context_data(object=self.object)
return self.render_to_response(context)