How to accommodate APIView & ViewSet views in urls.py - django

How would one write a urls.py file to accommodate views created from APIView and ViewSet.
entity.views.py
from .models import Entity
from .serializers import EntitySerializer
class EntityViewSet(DefaultsMixin, ListCreateRetrieveUpdateViewSet):
"""
"""
queryset = Entity.objects.all()
serializer_class = EntitySerializer
filter_fields = ('id', 'entity_number')
class PersonProfileList(APIView):
"""
person profile
"""
def get(self, request, format=None):
pass
entity.urls.py
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
entity_router = DefaultRouter()
entity_router.register(r'entity', views.EntityViewSet)
urlpatterns = [
url(r'profile/$', views.PersonProfileList.as_view(), name='profile_list'), # Is this correct?
url(r'profile/(?P<pk>[0-9]+)/$', views.PersonProfileList.as_view(), name='profile_detail'),
]
urlpatterns = format_suffix_patterns(urlpatterns)
main urls.py
from django.conf.urls import include, url
from django.contrib import admin
from entities.urls import entity_router, urlpatterns
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^entities/', include(entity_router.urls)), #This I know works
url(r'^entities/', include(urlpatterns.url)), # This throws errors
]
What is the best way to accommodate both types of Views in the same URL file and have them appear under one /entity unlike now when am getting two /entity entries. Also, once I get into the /entity page in the browsable API, how do I make the /entity/profile viewable since now it only shows /entity. See images for guide.
Root Page
Entities Page

Related

Converting to using URL router is causing a ImproperlyConfigured exception

I have been working through the Django Rest Framework tutorial and on the very last step I am encountering the error:
Exception Type: ImproperlyConfigured.
Exception Value:
Could not resolve URL for hyperlinked relationship using view name "snippet-detail". You may have failed to include the related model in your API, or incorrectly configured the lookup_field attribute on this field.
When trying to view either /settings/ or /users/ (visiting any user pages yields the same exception but with "user-detail" in place of "snippet-detail") as well as any specific indices of them, etc. All that works is root and login.
All my code thus far has been working fine and I'm very confused as to why copy-pasting from the tutorial would yield such catastrophic results
In comparing my snippets files with those available on the tutorial's repo I have not been able to find any significant difference (all that I've found is inconsistencies in whitespace). That being said, here is the code I'm using.
snippets/views.py:
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer, UserSerializer
from rest_framework import generics, permissions
from django.contrib.auth.models import User
from snippets.permissions import IsOwnerOrReadOnly
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework import renderers
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import permissions
from rest_framework import viewsets
class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
This viewset automatically provides `list` and `retrieve` actions.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
class SnippetViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
Additionally we also provide an extra `highlight` action.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly]
#action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
snippets/urls.py:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from snippets import views
# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet,basename="snippets")
router.register(r'users', views.UserViewSet,basename="users")
# The API URLs are now determined automatically by the router.
urlpatterns = [
path('', include(router.urls)),
]
snippets/serializers.py:
from django.contrib.auth.models import User
from rest_framework import serializers
from snippets.models import Snippet
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
highlight = serializers.HyperlinkedIdentityField(
view_name='snippet-highlight', format='html')
class Meta:
model = Snippet
fields = ('url', 'id', 'highlight', 'owner', 'title', 'code',
'linenos', 'language', 'style')
class UserSerializer(serializers.HyperlinkedModelSerializer):
snippets = serializers.HyperlinkedRelatedField(
many=True, view_name='snippet-detail', read_only=True)
class Meta:
model = User
fields = ('url', 'id', 'username', 'snippets')
tutorial/urls.py:
"""tutorial URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('snippets.urls')),
]
urlpatterns += [
path('api-auth/', include('rest_framework.urls')),
]
Router was being passed the wrong base names (plural forms of snippet and user rather than singular). Thanks to #IainShelvington for the answer in the comments!
To elaborate:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from snippets import views
# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet,basename="snippets")
router.register(r'users', views.UserViewSet,basename="users")
# The API URLs are now determined automatically by the router.
urlpatterns = [
path('', include(router.urls)),
]
should have been
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from snippets import views
# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet,basename="snippet")
router.register(r'users', views.UserViewSet,basename="user")
# The API URLs are now determined automatically by the router.
urlpatterns = [
path('', include(router.urls)),
]

Why am I getting error 404 in my django project when everything seems correct?

I have two apps in my Django project:basket and store. In root url files I configured the urls.py like this:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('store.urls', namespace='store')),
path('basket/', include('basket.urls', namespace='basket')),
store/urls.py:
from django.urls import path
from . import views
app_name = 'store'
urlpatterns = [
path('', views.all_products, name='all_products'),
path('<slug:slug>/', views.product_detail, name='product_detail'),
path('category/<slug:category_slug>/',
views.category_list, name='category_list')
]
basket/urls.py:
from django.urls import path
from . import views
app_name = 'basket'
urlpatterns = [
path('', views.basket_summary, name='basket_summary'),
path('add/', views.basket_add, name='basket_add'),
]
I am getting an error:
Page not found(404)
Request Method:GET
Request URL:http://127.0.0.1:8000/basket/
Raised by:store.views.product_detail
this is my store/views.py:
from django.shortcuts import get_object_or_404, render
from .models import *
def product_detail(request, slug):
product = get_object_or_404(Product, slug=slug, in_stock=True)
context = {
'product': product,
}
return render(request, 'store/products/detail.html', context)
please help me solve this problem i've been stuck on this for a long time.
Try this way if you want to avoid 404 error:
from django.shortcuts import get_object_or_404, render
from .models import *
def product_detail(request, slug):
try:
product = Product.objects.get(slug=slug, in_stock=True)
context = {
'product': product,
}
except Product.DoesNotExist:
raise ValidationError('Product Does not exist ')
return render(request, 'store/products/detail.html', context
)

page not found error in Django using a filter query {return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')}

I am making my first django practice project I have a view called PostListview :
from django.shortcuts import render
from django.utils import timezone
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from blog.models import Post, Comment
from blog.forms import PostForm,CommentForm
from django.urls import reverse_lazy
from django.views.generic import(TemplateView,ListView,DetailView,CreateView,UpdateView,
DeleteView)
class AboutView(TemplateView):
template_name = 'about.html'
class PostListView(ListView):
model = Post
def get_queryset(self):
return Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
I have this in in the urls:
from django.conf.urls import url
from blog import views
urlpatterns = [
url(r'^$',views.PostListView.as_view(), name= 'post_list'),
And this is the template which is calling this view.
<li class="navbar-brand bigbrand" >My Tech Blog</li>
This view is also set as the default home view and it opens fine at the time i open the site url (localhost) but when I am clicking "My Tech blog " it gives a 404 error.
This is the main urls.py :
from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from django.contrib.auth import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'',include('blog.urls')),
url(r'accounts/login/$',views.login, name = 'login'),
url(r'accounts/logout/$',views.logout, name = 'logout',kwargs={'next_page':'/'}),
]
Just change
url(r'^$',views.PostListView.as_view(), name= 'post_list'),
with
url(r'',views.PostListView.as_view(), name= 'post_list'),

'function' object has no attribute '__getitem__' django

getting type error at /. It may be too localized but I have been racking my brain and searching the web for an answer with no luck. Thank you in advance for your help
TypeError at /
'function' object has no attribute '__getitem__'
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 1.8.3
Exception Type: TypeError
Exception Value:
'function' object has no attribute '__getitem__'
Exception Location: /Users/wrb473/Documents/workspace/angulardjango/angulardjango/urls.py in <module>, line 22
Python Executable: /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
Python Version: 2.7.10
url.py
from django.conf.urls import patterns, include, url
from rest_framework.routers import DefaultRouter
#from rest_framework import routers
from django.contrib import admin
from django.contrib.auth.models import User
from rest_framework import routers,serializers,viewsets
from tweeter import views
admin.autodiscover()
router = DefaultRouter()
router = routers.SimpleRouter()
router.register(r'tweets', views.TweetViewSet,base_name='tweets')
router.register(r'users', views.UserViewSet,base_name='users')
urlpatterns = patterns['',
url(r'^admin/', include(admin.site.urls)),
url(r'^api/', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^$', views.index, name='index'),
]
here is my views.
views.py
from django.shortcuts import render
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_protect, ensure_csrf_cookie
from rest_framework import permissions, viewsets
from tweeter.models import Tweet
from tweeter.permissions import IsAuthorOrReadOnly
from tweeter.serializers import TweetSerializer, UserSerializer
#csrf_protect
#ensure_csrf_cookie
def index(request):
user = authenticate(username='bob', password='bob')
if user is not None:
login(request, user)
return render(request, 'tweeter/index.html')
class TweetViewSet(viewsets.ModelViewSet):
queryset = Tweet.objects.all()
serializer_class = TweetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsAuthorOrReadOnly,)
def pre_save(self, obj):
obj.user = self.request.user
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
Please help.
I think the problem is how you are defining your patterns.
urlpatterns = patterns['',
url(r'^admin/', include(admin.site.urls)),
url(r'^api/', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^$', views.index, name='index'),
]
As you can see in the django source for patterns, patterns is a function, so you need to call it, with (), not using [], which is the syntax to access an item in a sequence.
So you should do this instead:
urlpatterns = patterns(''
# ...
)

Where to store my index.html and index view for a non-static Django homepage

I'm creating a Django project and currently have 3 apps (products, questions and choices) - I've got them all functioning separately/together as I'd like and am using namespaces and include as part of my urls (my urls.py given below...)
### urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.views.generic import TemplateView
admin.autodiscover()
urlpatterns = patterns('',
url(r'^products/', include('products.urls', namespace='products')),
url(r'^questions/', include('questions.urls', namespace='questions')),
url(r'^choices/', include('choices.urls', namespace='choices')),
url(r'^admin/', include(admin.site.urls)),
)
Now I'm looking to add an index page (accessible at localhost:8000/) that will allow me to access all models created. I'm happy with my views.py...
## views.py
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views import generic
from products.models import Product
from questions.models import Question
from choices.models import Choice
class IndexView(generic.ListView):
template_name = 'index.html'
context_object_name = 'latest_product_list'
def get_queryset(self):
return Product.objects.all()
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['questions'] = Question.objects.all()
context['choices'] = Choice.objects.all()
return context
What I'd like to know is, what is the most sensible combination of urls.py entry, positioning of views.py and location of index.html to allow me to show a combination of my models on the landing page?
Thanks,
Matt
Create another app (I tend to name it home). That way, your home app can import models from products, questions and choices.
App layout
home/urls.py
home/views.py
home/templates/index.html
Include your home urls just like your other apps (but don't use a prefix)
url(r'^', include('home.urls', namespace='home')),