Unable to retrieve a single item when through HTTPRequest with Django Rest - python

I follow the instructions on Django Restframework tutorial here and has configured everything after it, but somehow, I can't use id to retrieve the json for a single item.
I expect to get a json representation of a single item when i request localhost:8080/items/[index], but instead of getting the item with the corresponding index I would get json representation of every items in I have.
My views.py
#api_view(['GET'])
def item_list(request):
"""
List and create items
"""
if request.method == 'GET':
items = Item.objects.all()
serializer = ItemSerializer(items, many=True)
return Response({'data': serializer.data })
#api_view(['GET'])
def item_detail(request, pk):
"""
Retrieve an item
"""
try:
item = Item.objects.get(pk=pk)
except Item.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = ItemSerializer(item)
return Response(serializer.data)
My urls.py in item module
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'$', views.item_list),
url(r'^items/(?P<pk>[0-9]+)/$', views.item_detail),
]
My urls.py in app module
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^', include('menu.urls')),
]
Edit: Thanks for the reply but it I think I have found a fix. It seems like by putting 'url(r'$', views.item_list)' in front all links will reroute to item_list(). The easy fix is just put it behind 'url(r'^items/(?P[0-9]+)/$', views.item_detail)'

switch the url paths in your url.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^items/(?P<pk>[0-9]+)/$', views.item_detail),
url(r'^$', views.item_list),
]
and include like
urlpatterns = [
path('admin/', admin.site.urls),
url(r'', include('menu.urls')),
]

Related

Views and HTTPresponse with user's data - Django

Given a GET the url is /home/data
Where data is a value that will depend on the user, that is, the complete domain will be
domain/home/data
What I want is to return an HTTP response depending on the data value
url.py
urlpatterns = [
path('admin/', admin.site.urls),
path('home/', home, name='home'),
]
views.py
def home (request):
response =item.objects.filter(radius<data)
return HttpResponse(response )
As you can see, radius is an attribute of the item model. And I want to filter all radius that are less than data.
How can I include data in that home function?
The path should then look like:
urlpatterns = [
path('admin/', admin.site.urls),
path('home/<int:data>/', home, name='home'),
]
such that it thus includes data as an int: You can then filter with the __lt lookup [Django-doc]:
def home(request, data):
# …
response = item.objects.filter(radius__lt=data)
# …
Of course here data needs to come from somewhere. You can not directly put item objects in a HttpResponse, a HTTP response is a stream of bytes. You can for example JSON serialize the data, or do some other encoding, but you can not use items in your response. You can for example use:
from django.core.serializers import serialize
from django.http import JsonResponse
from json import loads
def home(request, data):
response = item.objects.filter(radius__lt=data)
data = serialize('json', response)
return JsonRespnse({'data': loads(data)})
You would capture it from the URL like this
path('home/<data>/', home, name='home'),
You can get it in the view with
def home(request, data=None):

How to write urlpatterns in django?

I have this structure of urls:
page/section/subsection/article, where section, subsection and article are user-generated slug names.
How can I write the urlpatterns?
I do this, but may be exist better method?
urlpatterns = [
url(r'^$', views.index),
url(r'^(?P<slug>[-\w]+)/$', views.section),
url(r'^(?P<slug>[-\w]+)/(?P<subslug>[-\w]+)/$', views.subsection),
url(r'^(?P<slug>[-\w]+)/(?P<subslug>[-\w]+)/(?P<articleslug>[-\w]+)/$', views.article)
]
My views:
def index(request):
return render(request, 'MotherBeeApp/index.html', {})
def section(request, slug):
sections = Section.objects.filter(page=slug)
if sections:
return render(request, 'MotherBeeApp/section.html', {'Sections': sections})
else:
return render(request, 'MotherBeeApp/404.html', status=404)
def subsection(request, slug, subslug):
subsection = Section.objects.get(link_title=subslug)
articles = Article.objects.filter(section=subsection.pk)
page_title = subsection.title
return render(request, 'MotherBeeApp/subsection.html', {'Articles': articles, 'PageTitle': page_title})
def article(request, slug, subslug, articleslug):
article = Article.objects.get(link_title=articleslug)
return render(request, 'MotherBeeApp/article.html', {'Article': article})
If you are using Django version older than Django 2.0 (< 2.0) than you are doing right thing and you are already using optimistic way. but if your Django version is later than or equals to Django 2.0 you could write urlpatterns as shown here.
Maybe you can upgrade your Django to 2.0+, and then use code as follows:
from django.urls import path, include
urlpatterns = [
path('', views.index),
path('<slug:slug>/', include([
path('', views.section),
path('<slug:subslug>/', views.subsection),
path('<slug:subslug>/<articleslug>/', views.article),
])),
]

Trouble with namespace. Two different Urls are rendering the same view

I am having trouble with my urls. I have one app called users that has two models, Salon and Stylist. The url /stylists and /salons is rendering the same view (stylist_results) however /salons should render salon_results and I cannot figure out why. I think there may be something wrong with the way I am using namespaces.
users/urls.py
from django.conf.urls import url
#import views from the current directory
from . import views
urlpatterns=[
url(r'^$', views.stylist_results, name='stylist_results'),
url(r'^(?P<pk>\d+)$', views.stylist_detail, name='stylist_detail'),
url(r'^$', views.salon_results, name='salon_results'),
url(r'^(?P<pk>\d+)$', views.salon_detail, name='salon_detail'),
]
users/views.py
from django.shortcuts import get_object_or_404, render
from .models import Salon, Stylist
# Create your views here.
def salon_results(request):
salons = Salon.objects.all()
return render(request, 'salons/salon_results.html', {'salons': salons})
def salon_detail(request, pk):
salon = get_object_or_404(Salon, pk=pk)
return render(request, 'salons/salon_detail.html', {'salon': salon})
def stylist_results(request):
stylists = Stylist.objects.all()
return render(request, 'stylists/stylist_results.html', {'stylists': stylists})
def stylist_detail(request, pk):
stylist = get_object_or_404(Stylist, pk=pk)
return render(request, 'stylists/stylist_detail.html', {'stylist': stylist})
urls.py
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from . import views
urlpatterns = [
url(r'^salons/', include('users.urls', namespace='salons')),
url(r'^stylists/', include('users.urls', namespace='stylists')),
url(r'^admin/', admin.site.urls),
url(r'^$', views.home, name='home'),
]
urlpatterns += staticfiles_urlpatterns()
views.py
from django.shortcuts import render
def home(request):
return render(request, 'home.html')
Split your stylist and salon views into two separate modules. You might consider creating two different apps, but you don't have to.
users/stylist_urls.py
urlpatterns = [
url(r'^$', views.stylist_results, name='stylist_results'),
url(r'^(?P<pk>\d+)$', views.stylist_detail, name='stylist_detail'),
]
users/salon_urls.py
urlpatterns = [
url(r'^$', views.salon_results, name='salon_results'),
url(r'^(?P<pk>\d+)$', views.salon_detail, name='salon_detail'),
]
Then update your project's urls.py with the new modules:
urlpatterns = [
url(r'^salons/', include('users.salon_urls', namespace='salons')),
url(r'^stylists/', include('users.stylist_urls', namespace='stylists')),
...
]
At the moment, the regexes for your salon URLs are exactly the same as the stylist URLs, so the salon URLs will always match first.
You are specifying same set of url's(users.urls) for salons and stylists here:
url(r'^salons/', include('users.urls', namespace='salons')),
url(r'^stylists/', include('users.urls', namespace='stylists')),
What did you expect to happen
You are including same users/urls.py in urls.py
It does following:
find me /stylist/ => go into included urls
find first occurance of url(r'^$', views.stylist_results, name='stylist_results'),
renders that view
same thing happens with /salons/
URL Dispatcher documentation

Reverse for 'get_post' with arguments '()' and keyword arguments '{'slug': 'sample-post'}' not found

I am using django 1.9. While implementing class based views and urlpatterns I am not able to redirect my particular link to corresponding post.
settings/urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from posts.views import Home
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^post/', include("posts.urls")),
url(r'^$', Home.as_view(), name="blog_home"),
]
posts/urls.py
from django.conf.urls import url, include
from .views import Display
urlpatterns = [
url(r'^(?P<slug>\w+)/$', Display.as_view(), name="get_post"),
]
posts/views.py
class Display(View):
def get(self, request, slug):
params = {}
params['post'] = Post.objects.get(slug=slug)
return render(request, "blog/viewpost.html", params)
def post(self, request):
pass
and my error follows:
error is shown in that image
When you use the url regex r'^(?P<slug>\w+)/$, the \w matches alphanumeric characters and underscore. It will not, however, match hyphens -.
So, when your template looks for a URL with slug equal to sample-post, the above regex will not find a match. You should try using this instead:
urlpatterns = [
url(r'^(?P<slug>[-\w]+)/$', Display.as_view(), name="get_post"),
]

Django views and URl's

I'm having a problem with the way my URL's look in Django. I have a view like this:
def updatetext(request, fb_id):
Account.objects.filter(id=fb_id).update(display_hashtag=request.POST['hashtag'])
fb = get_object_or_404(Account, pk=fb_id)
return render(request, 'myapp/account.html', {
'success_message': "Success: Settings updated.",
'user': fb
})
When a user clicks on the URL to update the text they are then redirected to the account page but the URL then looks like 'account/updatetext/'. I would like it just be 'account/'.
How would I do this in Django. What would I use in place of render that would still allow me to pass request, 'success_message' and 'user' into the returned page but to not contain the 'updatetext' within the URL?
[edit]
The urls.py file looks like this:
from django.conf.urls import patterns, url
from myapp import views
urlpatterns = patterns('',
url(r'^home/$', views.index, name='index'),
url(r'^(?P<fb_id>\d+)/$', views.account, name='account'),
url(r'^(?P<fb_id>\d+)/updatetext/$', views.updatetext, name='updatetext'),
url(r'^(?P<fb_id>\d+)/updatepages/$', views.updatepages, name='updatepages'),
url(r'^login/$', views.user_login, name='login'),
url(r'^logout/$', views.user_logout, name='logout'),
url(r'^admin/$', views.useradmin, name='admin'),
)
You need to actually redirect the user to '/account/'. Rather than returning a call to render you can do the following:
from django.http import HttpResponseRedirect
def updatetext(request, fb_id):
Account.objects.filter(id=fb_id).update(display_hashtag=request.POST['hashtag'])
fb = get_object_or_404(Account, pk=fb_id)
return HttpResponseRedirect(reverse('account', kwargs={"fb_id": fb_id}))
However, it would be better to pass in a call to reverse into the HttpResponseRedirect constructor, but since I don't know your urls.py I just wrote the relative url.

Categories