I'm trying to set up my app in two languages, however I'm getting 404 error on all app's urls, even though I've set up another app a while ago the exact same way.
models.py:
class New(models.Model):
title = models.CharField(max_length=300)
slug = models.SlugField(max_length=300, editable=False)
pub_date = models.DateTimeField(auto_now_add=True)
text = models.TextField()
def __unicode__(self):
return self.title
def save(self, *args, **kwargs):
if not self.id:
# Newly created object, so set slug
self.slug = slugify(self.title)
super(New, self).save(*args, **kwargs)
translation.py:
class NewTranslationOptions(TranslationOptions):
fields = ('title','text')
translator.register(New, NewTranslationOptions)
urls.py:
urlpatterns += i18n_patterns('',
url(r'^categories/$', 'products.views.categories_index', name='categories_index'),
url(r'^(?P<category_slug>[\w-]+)/$', 'products.views.specific_category', name='specific_category'),
url(r'^(?P<category_slug>[\w-]+)/(?P<product_slug>[\w-]+)/$', 'products.views.specific_product', name='specific_product'),
url(r'^news/$', 'news.views.news_index', name='news_index'),
url(r'^news/(?P<news_slug>[\w-]+)/$', 'news.views.specific_new', name='specific_new'),
)
Here you can also see urls of my other app products, it works just fine. If you need anything else please let me know.
Your specific_category and specific_product url patterns are catching urls from news app:
>>> re.match("(?P<category_slug>[\w-]+)", "news").groups()
('news',)
Reorder your urls patterns:
urlpatterns += i18n_patterns('',
url(r'^categories/$', 'products.views.categories_index', name='categories_index'),
url(r'^news/$', 'news.views.news_index', name='news_index'),
url(r'^news/(?P<news_slug>[\w-]+)/$', 'news.views.specific_new', name='specific_new'),
url(r'^(?P<category_slug>[\w-]+)/$', 'products.views.specific_category', name='specific_category'),
url(r'^(?P<category_slug>[\w-]+)/(?P<product_slug>[\w-]+)/$', 'products.views.specific_product', name='specific_product'),
)
Or, consider adding category/ prefix to patterns from products app:
url(r'^category/(?P<category_slug>[\w-]+)/$', 'products.views.specific_category', name='specific_category'),
url(r'^category/(?P<category_slug>[\w-]+)/(?P<product_slug>[\w-]+)/$', 'products.views.specific_product', name='specific_product'),
Related
I want all djaango urls use slug field without any parameter before or after, by default
just one url can use this metod
Views.py
class ArticleDetail(DetailView):
def get_object(self):
slug = self.kwargs.get('slug')
article = get_object_or_404(Article.objects.published(), slug=slug)
ip_address = self.request.user.ip_address
if ip_address not in article.hits.all():
article.hits.add(ip_address)
return article
class CategoryList(ListView):
paginate_by = 5
template_name = 'blog/category_list.html'
def get_queryset(self):
global category
slug = self.kwargs.get('slug')
category = get_object_or_404(Category.objects.active(), slug=slug)
return category.articles.published()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['category'] = category
return context
urls.py
urlpatterns = [
path('<slug:slug>', ArticleDetail.as_view(), name="detail"),
path('<slug:slug>', CategoryList.as_view(), name="category"),
]
This is my django blog codes,
I don't want write article or category & ... in urls, just slug
mysite .com/article-slug
...
mysite .com/category-slug
It will always trigger the Article view, regardless if there is an Article for that slug. You thus should make the URL patterns non-overlapping such that the other views can be triggered, for example with:
path('article/<slug:slug>/', Article.as_View(), name="articledetail"),
path('category/<slug:slug>/', Category.as_View(), name="category"),
path('product/<slug:slug>/', Product.as_View(), name="productdetail"),
If you want a path that accepts a single slug, you should define a view that looks if there is an Article with that slug, if that is not the case a Category and if that is not the case a Product you thus implement that logic in the view, not in the URL patterns.
#WillemVanOlsem is right, you will have to write a view like this:
from django.http import HttpResponseNotFound
def slug_router(request, slug):
if Category.objects.filter(slug=slug).exists():
return CategoryList.as_view()(request, slug=slug)
elif Article.objects.filter(slug=slug).exists():
return ArticleDetail.as_view()(request, slug=slug)
else:
return HttpResponseNotFound('404 Page not found')
And then
urlpatterns = [
path('<slug:slug>', slug_router, name="slug"),
]
... if I'm not mistaken. This should be the jist of it.
I didn't test this code, just typed it in here, so let me know if it doesn't work, I'll help to fix it.
Note that you'll have a preference if there are Articles with the same slug as some Categories.
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.
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)