I am trying to get my blog posts to return a permalink so that I can ping them to blog directores, however when I call the permalink function I have created there is always an error. Everything I have found from googleing/stackoverflowing gets one error or another!
The most common error I am getting back is:
Reverse for 'viewpost' with arguments '()' and keyword arguments '{'slug': u'site-redesign'}' not found.
My model for this error:
class BlogPost(models.Model):
author = models.ForeignKey(User, related_name='posts')
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200)
...
#models.permalink
def get_absolute_url(self):
return ('viewpost', (), { 'slug':self.slug})
My urls.py:
urlpatterns = patterns('blog.views',
...
(r'^post/(?P<page_slug>[a-zA-Z0-9-]+)/$', 'viewpost'),
...
)
If i print: reverse('blogPost', kwargs={'slug': self.slug }) I get the correct url.
What am I doing wrong.
I am calling the function via:
signals.post_save.connect(
ping_directories(content_attr = 'body', url_attr = 'get_absolute_url'), sender = BlogPost, weak = False)
If you need any more info please let me know.
--EDIT more views
#pages
(r'^post/(?P<page_slug>[a-zA-Z0-9-]+)/$', 'viewpost'),
(r'^category/(?P<category_slug>[a-zA-Z0-9-]+)/page/(?P<page_number>[0-9]+)/$', 'viewcategories'),
(r'^category/$', 'listcategories'),
(r'^tag/(?P<tag_slug>[a-zA-Z0-9-]+)/page/(?P<page_number>[0-9]+)/$', 'viewtag'),
(r'^tag/$', 'listtags'),
(r'^category/(?P<category_slug>[a-zA-Z0-9-]+)/$', 'viewcategories'),
(r'^tag/(?P<tag_slug>[a-zA-Z0-9-]+)/$', 'viewtag'),
(r'^comments/', include('django.contrib.comments.urls')),
(r'^page/(?P<page_number>[0-9]+)/$', 'index'),
(r'^$', 'index'),
)
and the views:
def viewpost(request, page_slug):
blog_post = get_object_or_404(BlogPost, post_status = 'published', slug=page_slug)
path = settings.BLOG_PATH
return render_to_response("blog/detail.html", { "post": blog_post, "path":path}, context_instance=RequestContext(request))
You've called the kwargs page_slug in the url and slug in your permlink
Turns out that the method calling my get_absolute_url also needed an extra callback so I was getting misled. Apologies for the confusion! Offending code:
signals.post_save.connect(ping_directories(content_attr = 'body', url_attr = 'get_absolute_url', feed_url_fun=lambda x: 'http://example.com/feed/address/here/'), sender = BlogPost, weak = False)
Related
my problem is that I can not establish a reverse match, most likely doing something wrong with my url definition (?). Ultimately what I am trying to do is the following:
User selects 2 location points which the 'new_pointview' view, saves into a DB. I also define a unique slug which contains location information and save it to the DB via the save() within the model. Then the user should be redirected to a url (pointview view) which uses the slug I created in the previous step i.e /pointview/slug. Here is the code:
models.py
class Points(models.Model):
starting_point_longitude = models.FloatField(null=True)
starting_point_latitude = models.FloatField(null=True)
ending_point_longitude = models.FloatField(null=True)
ending_point_latitude = models.FloatField(null=True)
url = models.SlugField(max_length=250, null=True, unique=True, blank=False)
def save(self, *args, **kwargs):
self.url = 'start_lon-{0}-start_lat-{1}-end_lon-{2}-end_lat-' \
'{3}'.format(self.starting_point_longitude,
self.starting_point_latitude,
self.ending_point_longitude,
self.ending_point_latitude)
super(Points, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('pointview', kwargs={'url': self.url})
views.py
def pointview(request, url):
point = get_object_or_404(Points, url=url)
content = {'starting_point_longitude':
point.starting_point_longitude,
'starting_point_latitude':
point.starting_point_latitude,
'ending_point_longitude':
point.ending_point_longitude,
'ending_point_latitude':
point.ending_point_latitude}
return render(request, 'points.html', {'user_bundle': content})
def new_pointview(request):
Points.objects.create(
starting_point_longitude=request.POST['starting_point_longitude'],
starting_point_latitude=request.POST['starting_point_latitude'],
ending_point_longitude=request.POST['ending_point_longitude'],
ending_point_latitude=request.POST['ending_point_latitude'],
)
points_filtered = Points.objects.filter(
starting_point_longitude=request.POST[
'starting_point_longitude']).filter(
starting_point_latitude=request.POST[
'starting_point_latitude'])
unique_url = points_filtered.values()[0]['url']
return redirect('/pointview/{0}/'.format(unique_url))
urls.py
urlpatterns = [
path(r'^pointview/(?P<url>[-\w]+)/$', views.pointview, name='pointview'),
path('^new_pointview/', views.new_pointview, name='new_pointview'),
]
The error:
The current path, pointview/start_lon-738949.9146592747-start_lat--153698.8751025315-end_lon-759997.8063993475-end_lat--168467.65638300427/, didn't match any of URL patterns. Hope you can give me some feedback here..
For future reference, it was a regex problem, using the following non intuitive regex solved it:
url('^pointview/(?P<url>start_lon[--W]+start_lat[--W]+end_lon[--W]+end_lat[--W]+)/', views.pointview, name='pointview')
I would be very interesting though if someone can give a more elegant solution.
I'm trying to implement favorite feature so that user can choose favorite stores. I'm currently referencing the video https://www.youtube.com/watch?v=pkPRtQf6oQ8&t=542s and stuck with the beginning.
When I try to move to the url https://www.fake-domain.com/my-domain/like, it throws the error message saying No Store matches the given query. So, I guess self.kwargs.get("domainKey") this snippet seems to throw the error, but I don't know why.
I'm not sure if I'm showing my codes enough, so please let me know I need to show more.
models.py
class Store(models.Model):
...
domainKey = models.CharField(max_length=100)
likes = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
...
urls.py
url(r'^(?P<store_domainKey>.*)/$', views.detail, name='detail'),
url(r'^(?P<store_domainKey>.*)/like/$', views.StoreLikeRedirect.as_view(), name='like'),
views.py
class StoreLikeRedirect(RedirectView):
def get_redirect_url(self, *args, **kwargs):
store_domainKey = self.kwargs.get("domainKey")
print(store_domainKey)
obj = get_object_or_404(Store, pk='store_domainKey')
return obj.get_absolute_url()
--------------------------------EDIT------------------------------
Revised the codes based on the feedback, but still not working.
When I typed the url, the terminal says the following:
None <-- this is shown by print(store_domainKey) in views.py
Not Found: /down-east/like/
Since the print function in views.py prints None, I think there's something wrong on the line store_domainKey = self.kwargs.get("domainKey"). The part self.kwargs.get() seems not working. In the example video at the top of the post, the guy used SlugField(), but I used CharField() for my domainKey. Can it be an issue to use self.kwargs.get()?
views.py
class StoreLikeRedirect(RedirectView):
def get_redirect_url(self, *args, **kwargs):
store_domainKey = self.kwargs.get("domainKey")
print(store_domainKey)
obj = get_object_or_404(Store, domainKey=store_domainKey)
return obj.get_absolute_url()
urls.py
url(r'^(?P<store_domainKey>.*)/like/$', views.StoreLikeRedirect.as_view(), name='like'),
url(r'^(?P<store_domainKey>.*)/$', views.detail, name='detail'),
models.py
class Store(models.Model):
...
domainKey = models.CharField(max_length=100)
likes = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
...
def get_absolute_url(self):
return reverse('boutique:detail', kwargs={"domainKey":self.domainKey})
----------------------------2nd Update-----------------------------
So, now self.kwargs.get("domainKey") returns the domain key very well!
but having
NoReverseMatch at /down-east/like/
Reverse for 'detail' with arguments '()' and keyword arguments '{'domainKey': 'down-east'}' not found. 1 pattern(s) tried: ['(?P<store_domainKey>.*)/$']
In your view you are using a string instead of the variable you created. And you probably need to filter on the field domainKey instead of pk.
Try changing
obj = get_object_or_404(Store, pk='store_domainKey')
to
obj = get_object_or_404(Store, domainKey=store_domainKey)
I have been chopping away at this for a few days with no clue as to why its not working. I have two views, one to list tools and one to list parts. I also have the list and detail URL's for both. Both list views work and the tool detail view works, but when I click on a part item to see the detail, the correct url appears in the browser, but I get an error shown in the screenshot below, which as you can see is trying to use the tool_detail view. Thank you for looking.
Here is my code for review:
url:
from .views import tool_list, part_list, tool_detail, part_detail
urlpatterns = [
url(r'^products/tools/$', tool_list, name='tool_list'),
url(r'^products/(?P<category>[^\.]+)/(?P<slug>[^\.]+)/$', tool_detail, name='tool_detail'),
url(r'^products/parts/$', part_list, name='part_list'),
url(r'^products/(?P<category>[^\.]+)/(?P<slug>[^\.]+)/$', part_detail, name='part_detail'),
]
view:
def tool_list(request):
tools = Tool.objects.prefetch_related('uploads').all()
return render(request, 'tool_list.html', {'tools': tools})
def tool_detail(request, **kwargs):
tool = get_object_or_404(Tool, slug=kwargs.get('slug'))
return render(request, 'tool_detail.html', {'tool': tool})
def part_list(request):
parts = Part.objects.prefetch_related('uploads').all()
return render(request, 'part_list.html', {'parts': parts})
def part_detail(request, **kwargs):
part = get_object_or_404(Part, slug=kwargs.get('slug'))
return render(request, 'part_detail.html', {'part': part})
models
class Part(Timestamp):
model_number = models.ForeignKey(ModelNumber, related_name='part_model_number')
category = models.ForeignKey(Category, related_name='part_category')
price = models.DecimalField(max_digits=10, decimal_places=2)
title = models.CharField(max_length=250)
slug = models.SlugField(help_text="slug-title-should-be-like-this")
...
class Tool(Timestamp):
model_number = models.ForeignKey(ModelNumber, related_name='tool_model_number')
price = models.DecimalField(max_digits=10, decimal_places=2)
title = models.CharField(max_length=250)
slug = models.SlugField(help_text="slug-title-should-be-like-this")
category = models.ForeignKey(Category, related_name='tool_category')
...
The first url pattern that matches is what Django will use to dispatch to a view. The 2nd url matches, so it's using the tool_detail view.
What I'm trying to achieve is: my News app should display a slug, but only query the article by ID in the form of /news/24/this-is-the-slug
Unfortunately I'm getting a NoReverseMatch: Reverse for 'news_detail' with arguments '('',)' and keyword arguments '{}' not found. when trying to browse an article. The URL generated in the template looks correct as stated above (I can confirm this by doing a search via Haystack, which delivers the correct URL).
models.py
class News(models.Model):
id = models.IntegerField(primary_key=True, editable=False)
category = models.CharField(max_length=50L)
title = models.CharField(max_length=200L)
rss_summary = models.TextField(max_length=2000L)
body_text = models.TextField(max_length=5000L)
post_date = models.DateTimeField()
prettyurl = models.SlugField(max_length=100L)
class Meta:
db_table = 'news'
def __unicode__(self):
return self.title
def get_absolute_url(self):
return urlresolvers.reverse('news_detail', kwargs={'pk': self.id, 'slug': self.prettyurl })
urls.py
urlpatterns = patterns(
'',
url(
r'^$',
view=views.NewsListView.as_view(),
name='news_index'),
url(
r'^(?P<pk>\d+)/',
view=views.NewsDetailView.as_view(),
name='news_detail'),
url(
r'^(?P<pk>\d+)/(?P<slug>[-\w]+)/$',
view=views.NewsDetailView.as_view(),
name='news_detail'),
url(
r'^archive/$',
view=views.NewsArchiveIndexView.as_view(),
name="archive_month"),
[... more unrelated urls ...]
views.py
class NewsDetailView(DetailView):
#name='news_detail'),
model = News
context_object_name = 'news'
#slug_url_kwarg = 'prettyurl'
#slug_field = 'prettyurl'
template_name = 'news/detail.html'
Template
`<p>Permalink for this article.`
Thanks #Daniel Roseman and #yuvi. With your help I managed to solve my problem by defining the URL pattern to this:
r'^(?P<pk>\d+)(?:/(?P<slug>[\w\d-]+))?/$',
Which allows all my wanted forms of
news/nn
news/nn/
news/nn/a-slug
news/nn/a-slug/
In the template, I use
{% url 'news_detail' news.id news.prettyurl %}
Which shows the fourth version in the listing above.
Thanks again!
I'm not quite sure why you're bothering to capture the slug at all. Rather than having a named group in the URL pattern, you could just have one that ignores everything after the PK:
r'^(?P<pk>\d+)/.*',
which would work just as well whether or not you passed the slug, so you could then get rid of your duplicated patterns.
There are two basic problems with what you have, though. Firstly, even though you state you want to actually match only on PK, you don't even pass the PK to the URL, just the slug. Secondly, even the slug appears to be blank, as the error message states (the args variable is just '').
You should instead pass the actual PK:
{% url 'news_detail' news.pk %}
As you can see by the tittle I have a weird Caught NoReverseMatch while rendering: Reverse for 'accounts_profile_view' with arguments '('',)' and keyword arguments '{}' not found.
The weirdest thing is when using shell_plus in django, importing a user profile, then importing the reverse function from django.urlcore.resolvers I do this:
reverse('accounts_profile_views', args=[username])
and it works just fine!
I created a bunch of gist for you guys to help me out review them, here they are.
This is the model
https://gist.github.com/140127f6303660baf8d9
This is my views file
https://gist.github.com/1a3b9651eef3fb9d22db
This is my model urls
https://gist.github.com/66fe6b1f068739f940db
and this is the whole project url
https://gist.github.com/edea781b1efca341230b
and of course the error
https://gist.github.com/8b84bd0394d4b047dce8
Thanks for your help community!
====== UPDATE ======
I found something out, theres something weird happening on the contact_us view and template, when I go to the contact-us page the request.user.username on the header shows an empty var.
Heres my contact_us url which is part of the main views for the project:
from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('apps.maincoke.views',
url(r'^(?i)$', 'home', name='home'),
url(r'^(?i)faqs/$', direct_to_template, {'template': 'maincoke/faqs.html'}, name="main_faqs"),
url(r'^(?i)contact-us/$','contact_us', name='contact_us'),
)
This is the contact_us view:
#login_required
#render_to("maincoke/contact_us.html")
def contact_us(request):
mail_status = None
if request.method == 'POST':
contact_us_form = ContactUsForm(request, request.POST)
if contact_us_form.is_valid():
mail_status = contact_us_form.send_as_mail()
if mail_status:
contact_us_form = ContactUsForm(request)
else:
contact_us_form = ContactUsForm(request)
return { 'contact_us_form' : contact_us_form, 'mail_status' : mail_status }
and this is the form, Im using django-uni-form
class ContactUsForm(forms.Form):
name = forms.CharField(label='Nombre', max_length=120, required=True)
email = forms.CharField(max_length=200, required=True)
message = forms.CharField(label='Mensaje', widget=forms.Textarea(attrs={'cols':'40'}),
required=True)
MAX_MESSAGE_LENGTH = 2000
# uniForm Helper
helper = FormHelper()
helper.form_id = "contact_us_form"
layout = Layout(
Fieldset('',
'name', 'email', 'message'
)
)
helper.add_layout(layout)
# Submit button(s)
submit = Submit('submit','Enviar')
helper.add_input(submit)
class Meta:
fields = ['name', 'email', 'message']
def __init__(self, request, *args, **kw):
super(ContactUsForm, self).__init__(*args, **kw)
self.request = request
def clean_message(self):
message_data = self.cleaned_data['message']
if len(message_data) > self.MAX_MESSAGE_LENGTH:
raise forms.ValidationError("Mensaje demasiado largo")
def send_as_mail(self):
data = self.cleaned_data
send_status=True
mail_content_html = render_to_string('mails/contactmail.html', {'data':data})
mail_content_text = strip_tags(mail_content_html)
mail = EmailMultiAlternatives("Mensaje enviado de %s" % data['name'],
mail_content_text,
settings.DEFAULT_FROM_EMAIL,
settings.CONTACT_MAIL_RECIPIENT
)
mail.attach_alternative(mail_content_html, "text/html")
try:
mail.send(fail_silently=False)
except:
send_status=False
return send_status
The information of the template is not getting rendered at all!
The error is showing you what's wrong: the username argument is evaluating to an empty string. You'll need to work out why this is.
from django.conf.urls.defaults import *
urlpatterns = patterns('apps.accounts.views',
url(r'^(?P<username>\w+)/$', 'profile_view', {}, name="accounts_profile_view"),
url(r'^(?P<username>\w+)/edit/$', 'profile_edit', {}, name="accounts_profile_edit"),
)
It happens when the data represented here: r'^(?P username \w+) does not match with the given data in the reverse def: reverse('accounts_profile_views', args=[username])
\w Match a word character (alphanumeric plus "_")
Debug the view and see whats in this username, if this contains a space, or dot, or empty string as our PyMASTER #Daniel Roseman says... this wont match and will raise this exception.