How to HyperlinkedRelatedField into a model from different app? - python

bellow is urls.py of users app.
from django.urls import path
from . import views
app_name = 'users'
urlpatterns = [
path('', views.UserList.as_view(), name='user-list'),
path('<int:id>/', views.UserDetail.as_view(), name='user-detail'),
]
url conf of snippets app:
from django.urls import path
from . import views
app_name = 'snippets'
urlpatterns = [
path('', views.SnippetList.as_view(), name='snippet-list'),
path('<int:pk>/', views.SnippetDetail.as_view(), name='snippet-detail'),
path('<int:pk>/highlight/', views.SnippetHighlight.as_view(), name='snippet-highlight'),
]
and here's SnippetSerializer
from rest_framework import serializers
from . import models
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Snippet
fields = ['id', 'owner', 'title', 'code', 'highlight', 'linenos', 'language', 'style']
highlight = serializers.HyperlinkedIdentityField(view_name='snippets:snippet-highlight', format='html')
owner = serializers.HyperlinkedRelatedField(
read_only=True,
view_name='users:user-detail'
)
The error I got
ImproperlyConfigured at /snippets/
Could not resolve URL for hyperlinked relationship using view name "users:user-detail". You may have failed to include the related model in your API, or incorrectly configured the lookup_field attribute on this field.

My mistake was that I specified id instead of pk in url pattern of users app.
Such things make me feel frustrated.

Related

django ImpropertlyConfigured. The included urlsconf does not appear to have any patterns in it

I am using django 2.2.2 . I am trying to include path('api/', include('music.urls')),into my root url but I get an exception thrown from resolvers.py file.
Here is my music/urls.py
urls.py
from django.urls import path
from . import views
app_name = 'music'
urlpatterns = [
path('songs/', ListSongsView.as_view(), name = 'songs-all'),
]
here is my root url file
urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('music.urls')),
]
views.py
from django.shortcuts import render
from rest_framework import generics
from .models import Songs
from serializers import SongSerializer
# Create your views here.
class ListSongsView(generics.ListApiView):
queryset = Songs.objects.all()
serializer_class = SongsSerializer
models.py
from django.db import models
# Create your models here.
class Songs(models.Model):
title = models.CharField(max_length=255, null = False)
artist = models.CharField(max_length=50, null= False)
def __str__(self):
return "{} - {}".format(self.title, self.artist)
and my stacktrace
File "/home/brianonchari/Documents/django/drf/myapi/lib/python3.5/site-
packages/django/urls/resolvers.py", line 588, in url_patterns
raise ImproperlyConfigured(msg.format(name=self.urlconf_name))
django.core.exceptions.ImproperlyConfigured: The included URLconf 'rest.urls' does not
appear to have any patterns in it. If you see valid patterns in the file then the issue is
probably caused by a circular import.
music/urls.py
from django.urls import path
from .views import ListSongsView
app_name = 'music'
urlpatterns = [
path('songs/', ListSongsView.as_view(), name='songs-all'),
]
root urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('music.urls')),
]
music/views.py:
from django.shortcuts import render
from rest_framework import generics
from .models import Songs
from .serializers import SongSerializer
# Create your views here.
class ListSongsView(generics.ListAPIView):
queryset = Songs.objects.all()
serializer_class = SongSerializer
music/models.py:
from django.db import models
# Create your models here.
class Songs(models.Model):
title = models.CharField(max_length=255, null=False)
artist = models.CharField(max_length=50, null=False)
def __str__(self):
return "{} - {}".format(self.title, self.artist)
music/serializers.py:
from rest_framework import serializers
from .models import Songs
class SongSerializer(serializers.ModelSerializer):
class Meta:
model = Songs
fields = ('title', 'artist')
run your migration for Songs model:
python manage.py makemigrations
python manage.py migrate

Trying to trace a circular import error in Django Python

I understand circular import error has been asked about a lot but after going through these questions I haven't been able to solve my issue. When I try to run my server in Django, it is giving me this error message:
django.core.exceptions.ImproperlyConfigured: The included URLconf 'starsocial.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.
The issue started when I added a new app which has a urls.py like the following:
from django.conf.urls import url
from django.contrib.auth import views as auth_views
from . import views
app_name = 'accounts'
urlpatterns = [
url(r'login/$',
auth_views.LoginView.as_view(template_name='accounts/login.html'),
name='login'),
url(r'logout/$',auth_views.LogoutView.as_view(), name='logout'),
url(r'signup/$',views.SignUp.as_view(), name='signup'),
]
My project urls.py has a line which points to the app and looks like the following code:
from django.contrib import admin
from django.urls import path,include
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^admin/',admin.site.urls),
url(r'^$', views.HomePage.as_view(), name='home'),
url(r'^accounts/', include('accounts.urls', namespace='accounts')),
url(r'^accounts/', include('django.contrib.auth.urls')),
url(r'^test/$', views.TestPage.as_view(), name='test'),
url(r'^thanks/$', views.ThanksPage.as_view(), name='thanks')
]
My application's view looks like the following:
from django.shortcuts import render
from django.urls import reverse
from django.views.generic import CreateView
from . import forms
# Create your views here.
class SignUp(CreateView):
form_class = forms.UserCreateForm
success_url = reverse('login')
template_name = 'accounts/signup.html'
My project's view looks like:
from django.views.generic import TemplateView
class TestPage(TemplateView):
template_name = 'test.html'
class ThanksPage(TemplateView):
template_name = 'thanks.html'
class HomePage(TemplateView):
template_name = 'index.html'
Can anyone please help me identify where I could possibly be going wrong.
You are importing auth.urls twice. Remove url(r'^accounts/', include('django.contrib.auth.urls')) from your project's urls.py
I am importing wrong URL configuration, instead of 'reverse' I should import 'reverse_lazy',
change
from django.shortcuts import render
from django.urls import reverse
from django.views.generic import CreateView
from . import forms
# Create your views here.
class SignUp(CreateView):
form_class = forms.UserCreateForm
success_url = reverse('login')
template_name = 'accounts/signup.html'
to
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import CreateView
from . import forms
# Create your views here.
class SignUp(CreateView):
form_class = forms.UserCreateForm
success_url = reverse_lazy('login')
template_name = 'accounts/signup.html'

how to make drf HyperlinkedModelSerializer elegantly work with app_name?

I am using drf in django project
# project/urls.py
from django.urls import include, path
urlpatterns = [
...
path('drf/', include('api.urls')),
...
]
in a dedicated app which I namespaced via app_name as following:
# api/urls.py
from django.urls import include, path
from rest_framework import routers
from . import views
app_name = 'drf'
router = routers.SimpleRouter()
router.register('segments', views.SegmentViewSet)
urlpatterns = [
path('', include(router.urls)),
]
# api/serializers.py
from rest_framework import serializers
from segment.models import Segment
class SegmentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Segment
fields = ['id', 'url', 'name']
# api/views.py
from rest_framework import viewsets
from .serializers import SegmentSerializer
from segment.models import Segment
class SegmentViewSet(viewsets.ModelViewSet):
queryset = Segment.objects.all()
serializer_class = SegmentSerializer
calling endpoint /drf/segments/ results in the following error:
ImproperlyConfigured at /drf/segments/
Could not resolve URL for hyperlinked relationship using view name "segment-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
Request Method: GET
Request URL: http://localhost:8000/drf/segments/
Django Version: 2.2.7
Python Executable: /Users/udos/.virtualenvs/ts/bin/python
Python Version: 3.6.4
.
.
.
to "fix" this, I have to add the following code to the serializer:
url = serializers.HyperlinkedIdentityField(
view_name='drf:segment-detail',
)
resulting in:
# api/serializers.py
from rest_framework import serializers
from segment.models import Segment
class SegmentSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='drf:segment-detail',
)
class Meta:
model = Segment
fields = ['id', 'url', 'name']
I have to do this for all entities (which I would like to avoid).
is there a way to handle this without using the extra code? some magic method/attribute to call/set?

Using Django REST Framework API for data model with composite key

How do you use Django Rest Framework to create an API when the data model has a composite key consisting of two fields? Background: I am trying to make a REST api for a data model (sample data row below- first two entries make the composite key). I am able call upon my data with date field but am getting errors when I try to use the second string field to return a single record.
'2015-05-06','INTC','31.93','32.79','32.50','32.22','31737537'
I am trying to make the api url structure like so:
localhost/api/v1/yyyy-mm-dd/'char'
localhost/api/v1/2015-05-07/AAPL
serializers.py
from rest_framework import serializers
from .models import Stocksusa, Optionsusa
from rest_framework.reverse import reverse
class StocksUsaSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.SerializerMethodField('get_stock_usa_url')
def get_stock_usa_url(self, obj):
values = [obj.Trade_Date, obj.Ticker]
composite_key_url = "http://0.0.0.0:9978/api/v1/stocksusa/{}/{}".format(*values)
return composite_key_url
class Meta:
model = Stocksusa
fields = ('Trade_Date', 'Ticker', 'PxMin', 'PxMax', 'PxOpen', 'PxClose', 'Volume', 'url')
views.py
from django.shortcuts import render
from rest_framework import authentication, permissions, viewsets, filters
from .models import Stocksusa
from .serializers import StocksUsaSerializer
from django.contrib.auth import get_user_model
User = get_user_model()
class DefaultsMixin(object):
authentication_classes = (
authentication.BasicAuthentication,
authentication.TokenAuthentication,
)
permission_classes = (
permissions.IsAuthenticated,
)
paginate_by = 25
paginate_by_param = 'page_size'
max_paginate_by = 100
filter_backends = (
filters.DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter,
)
class StocksUsaViewSet(DefaultsMixin, viewsets.ReadOnlyModelViewSet):
queryset = Stocksusa.objects.all()
serializer_class = StocksUsaSerializer
app/urls.py
from rest_framework.routers import DefaultRouter
from . import views
router = DefaultRouter(trailing_slash=False)
router = DefaultRouter()
router.register(r'stocksusa', views.StocksUsaViewSet)
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf.urls import include, url
from rest_framework.authtoken.views import obtain_auth_token
from FinDataUsa.urls import router
from FinDataUsa.views import StocksUsaViewSet as stockview
urlpatterns = patterns('',
url(r'^api/token/', obtain_auth_token, name='api-token'),
url(r'^api/v1/', include(router.urls)),
url(r'^api/v2/', include(router.urls)),
url(r'^admin/', include(admin.site.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^docs/', include('rest_framework_swagger.urls')),
)
The problem lies into the fact that the DefaultRouter uses the id lookup_field of your model for getting the object you want: For example this works:
GET localhost/api/v1/stocksusa/1
In order to provide extra parameters you need to hand-craft the urls like this:
url(r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})/(?P<code>\w+)$',
StocksUsaViewSet.as_view(),
name='stocks_detail'
),
The year month day code parameters are passed into your view with the kwargs dictionary:
self.kwargs['year']
self.kwargs['month']
self.kwargs['day']
self.kwargs['code']
On your get_object method you need to do something like that:
def get_object(self, queryset=None):
try:
date= datetime.date(
year=int(self.kwargs['year']),
month=int(self.kwargs['month']),
day=int(self.kwargs['day']),
)
except ValueError:
raise Http404
stock= get_object_or_404(Stocksusa, Ticker=self.kwargs['code'], Trade_Date=date)
return stock
Then you will have access to your object:

Struggling to get django_comments to work with Django REST Framework

I'm using Django REST Framework for the first time on a project and I'm struggling with one particular part. The project is an issue tracker-type applicaton and it uses django_comments to allow for comments on issues. I'm now building an API on top of it to allow for creating a mobile app.
I've created the following serializers:
from django.contrib.auth.models import User
from todolist.models import Project, Issue
from rest_framework import serializers
from django_comments.models import Comment
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('id', 'email', 'first_name', 'last_name')
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Project
fields = ('name', 'description', 'owner')
class CommentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Comment
class IssueSerializer(serializers.HyperlinkedModelSerializer):
comments = CommentSerializer(many=True)
class Meta:
model = Issue
And here's my project-wide urls.py, where I define the routes:
from django.conf.urls import patterns, include, url
from todolist.views import HomeTemplateView, UserViewSet, ProjectViewSet, IssueViewSet, CommentViewSet
from rest_framework import routers
from rest_framework.authtoken.views import obtain_auth_token
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'projects', ProjectViewSet)
router.register(r'issues', IssueViewSet)
router.register(r'comments', CommentViewSet)
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'projectile.views.home', name='home'),
# url(r'^projectile/', include('projectile.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
# Comments
(r'^comments/', include('django_comments.urls')),
# Login
url(r'^accounts/login/$', 'django.contrib.auth.views.login'),
# Logout
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login', {'login_url': '/accounts/login/'}),
# To-do list
url(r'^projects/', include('todolist.urls')),
# Home page
url(r'^$', HomeTemplateView.as_view(
template_name="todolist/home.html",
)),
# Router URLs
url(r'^api/', include(router.urls)),
# REST framework auth URLs
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api-token-auth/', obtain_auth_token),
# API docs
url(r'^docs/', include('rest_framework_swagger.urls'))
)
I'm seeing the following error when I run a test which tries to get all the comments:
ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "contenttype-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
Also, when I fetch an issue, it doesn't include the comments.
Now, this error appears to me to be that when fetching a comment, it's unable to match up the comment to its parent. I've experienced similar problems when using Tastypie in the past, and I'm unsure how to resolve it with DRF.
In your Comment serializer, specify comment instances fields explicitly and exclude field contenttype.
class CommentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Comment
fields = ('field_1','field_2','field_3') #here goes your comment fields and dont include contenttype field
The problem is that DRF will try to apply hyperlinks to represent all relationships, and for contenttype field you don't have a view or a serializer and you dont need it either.

Categories