I have a simple django project and whenever i run it, it gives me an improperly configured error. Tells me my model is missing a query set:
Improperly Configured Error Image
Here's the code for my views.py. The functionality doesn't matter for now:
import random
from django.shortcuts import render
from django.http import HttpResponse
from django.views import View
from django.views.generic import TemplateView
from django.views.generic.list import ListView
class RestaurantList(ListView):
querySet = Restaurant.objects.all()
template_name = 'restaurants/restaurants_list.html'
class SpicyList(ListView):
template_name = 'restaurants/restaurants_list.html'
querySet = Restaurant.objects.filter(category__iexact='spicy')
class AsianList(ListView):
template_name = 'restaurants/restaurants_list.html'
querySet = Restaurant.objects.filter(category__iexact='asian')
Here's the code for my models.py
from django.db import models
class Restaurant(models.Model):
name = models.CharField(max_length=120)
loocation = models.CharField(max_length=120, null=True, blank=True)
category = models.CharField(max_length=120, null=True, blank=False)
timestamp = models.DateTimeField(auto_now=True)
updated = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
urls.py code:
from django.contrib import admin
from django.conf.urls import url
from django.views.generic import TemplateView
from restaurant.views import *
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', TemplateView.as_view(template_name='home.html')),
url(r'^restaurants/$', RestaurantList.as_view()),
url(r'^restaurants/asian/$', AsianList.as_view()),
url(r'^restaurants/spicy/$', SpicyList.as_view()),
url(r'^Contact/$', TemplateView.as_view(template_name='Contact.html')),
url(r'^About/$', TemplateView.as_view(template_name='About.html'))
]
It's only the urls containing 'restaurants' that give me this error. The rest are fine.
Here's a picture of my file structure at the side
File Structure
The queryset attribute should be lower case at all.
all your views contain querySet
replace them by queryset lower case
Or you can provide the model attribute model = ModelName
See more In the Official Documentation
Related
A newbie here in the world of Django. I am struggling with creating a hyperlink for a nested route.
The error I am getting is:
Could not resolve URL for hyperlinked relationship using view name "rest:campaign-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
Some project setup notes
Using django rest framework
using DRF-extensions to create the routes
Using ModelViewSet
Expected end points:
/accounts/
/accounts/< pk >/
/accounts/< pk >/campaigns/
/accounts/< pk >/campaigns/< pk >/
/accounts/< pk >/campaigns/adgroup/
/accounts/< pk >/campaigns/adgroup/< pk >/
Set a namespace of rest in urls.py
Using HyperlinkedIdentityField to create the hyperlink. It only works with the parent object i.e.
url = serializers.HyperlinkedIdentityField(view_name='rest:account-detail')
However fails with any nested object i.e.
url = serializers.HyperlinkedIdentityField(view_name='rest:campaign-detail')
The model is quiet simple, an Account can have many Campaigns, and a campaign can have many AdGroups. See code below:
models.py
from django.db import models
from django.db.models import Q
from model_utils import Choices
ORDER_COLUMN_CHOICES = Choices(
('0', 'id'),
('1', 'keyword'),
('2', 'status'),
('3', 'match_type'),
)
# Account
class Account(models.Model):
account_name = models.CharField(max_length=128)
def __str__(self):
return self.account_name
# Campaign
class Campaign(models.Model):
class Status(models.TextChoices):
Enabled = "Enabled"
Paused = "Paused"
account = models.ForeignKey(
to=Account, on_delete=models.CASCADE, related_name='campaigns'
)
campaign_name = models.CharField(max_length=128)
status = models.CharField(max_length=21, choices=Status.choices, default=Status.Paused)
def __str__(self):
return self.campaign_name
# AdGroup
class AdGroup(models.Model):
class Status(models.TextChoices):
Enabled = "Enabled"
Paused = "Paused"
campaign = models.ForeignKey(
to=Campaign, on_delete=models.CASCADE, related_name='adgroups'
)
adgroup_name = models.CharField(max_length=128)
status = models.CharField(max_length=21, choices=Status.choices, default=Status.Enabled)
def __str__(self):
return self.adgroup_name
views.py
from rest_framework import viewsets
from .serializers import *
from . import models
from rest_framework_extensions.mixins import NestedViewSetMixin
class AccountViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
serializer_class = AccountSerializer
queryset = models.Account.objects.all()
class CampaignViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
serializer_class = CampaignSerializer
queryset = models.Campaign.objects.all()
class AdGroupViewSet(NestedViewSetMixin, viewsets.ModelViewSet):
serializer_class = AdGroupSerializer
queryset = models.AdGroup.objects.all()
serializers.py
from rest_framework import serializers
from . import models
class CampaignSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="rest:campaign-detail")
class Meta:
model = models.Campaign
fields = '__all__'
class AccountSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='rest:account-detail')
class Meta:
model = models.Account
fields = '__all__'
class AdGroupSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='rest:adgroup-detail')
class Meta:
model = models.AdGroup
fields = '__all__'
I have 2 URL files. The project is named Vanilla and an app named rest where the DRF logic sits.
Vanilla urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('rest.urls', namespace='rest')),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path('admin/', admin.site.urls)
]
Rest urls.py
from django.urls import include, path
from . import views
from rest_framework_extensions.routers import ExtendedSimpleRouter
app_name = 'rest'
router = ExtendedSimpleRouter()
(
router.register(r'accounts',
views.AccountViewSet,
basename='account')
.register(r'campaigns',
views.CampaignViewSet,
basename='campaign',
parents_query_lookups=['account__id'])
.register(r'adgroups',
views.AdGroupViewSet,
basename='adgroup',
parents_query_lookups=['campaign__account', 'campaign'])
Thank You!
use hyperlinkedModelSerializer in all of your related serializer. that should work
Iam trying to access http://localhost:8000/api/movies/. But, it showing like this ..AssertionError at /api/movies/ 'MovieViewSet' should either include a queryset attribute, or override the get_queryset() method. I attached my code below
models.py
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator,MaxValueValidator
class Movie(models.Model):
title = models.CharField(max_length = 32)
description = models.TextField(max_length =300)
def __str__(self):
return self.title
class Rating(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
stars = models.IntegerField(validators=[MinValueValidator(1),MaxValueValidator(5)])
class Meta:
unique_together =(("user","movie"),)
index_together =(("user","movie"),)
serializers.py
from rest_framework import serializers
from .models import Movie,Rating
class MovieSerializer(serializers.ModelSerializer):
class Meta:
model = Movie
fields = ('id','title','description')
class RatingSerializer(serializers.ModelSerializer):
class Meta:
model = Rating
fields = ('id','stars','user','movie')
urls.py
from django.contrib import admin
from django.urls import path
from rest_framework import routers
from django.conf.urls import include
from .views import MovieViewSet,RatingViewSet
router = routers.DefaultRouter()
router.register('movies',MovieViewSet,basename='movies')
router.register('ratings',RatingViewSet,basename='ratings')
urlpatterns = [
path('', include(router.urls)),
]
views.py
from django.shortcuts import render
from rest_framework import viewsets
from .models import Movie,Rating
from .serializers import MovieSerializer,RatingSerializer
class MovieViewSet(viewsets.ModelViewSet):
query_set = Movie.objects.all()
serializer_class = MovieSerializer
class RatingViewSet(viewsets.ModelViewSet):
query_set = Rating.objects.all()
serializer_class = RatingSerializer
You should use queryset in your views.py, not query_set
I am using Django 3.0 djangorestframework==3.11.0. I have created a task update view and passing the pk to url. The problem is - Although I have set the serializer instance to the model object I want to update. The serializer instance is not showing up.
models.py
from django.db import models
# Create your models here.
class Task(models.Model):
title = models.CharField(max_length=200)
completed = models.BooleanField(default=False, blank=True, null=True)
def __str__(self):
return self.title
serializers.py
from rest_framework import serializers
from .models import Task
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = '__all__'
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.apiOverview, name='api-overview'),
path('task-list/', views.taskList, name='task-list'),
path('task-detail/<str:pk>/', views.taskDetail, name='task-detail'),
path('task-create/', views.taskCreate, name='task-create'),
path('task-update/<str:pk>/', views.taskUpdate, name='task-update'),
]
views.py
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Task
from .serializers import TaskSerializer
#api_view(['POST'])
def taskUpdate(request, pk):
task = Task.objects.get(id=pk)
serializer = TaskSerializer(instance=task, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
expected behavior on url http://localhost:8000/api/task-update/4/
actual behaviour on http://localhost:8000/api/task-update/4/
as you can see the content field is empty but I want the already associated json to be shown there with pk = 4.
I am the newbie of writing programming, now I am learning django.
I have a problem for URL redirection. I create the model and it does work at admin site.
Also I set the PK for each article, that successfully generate the URL by PK.
However when I post the message form the front-end, after posting it appear the error message suppose it should be redirect to the page of DetailViewand
I have imported the reverse function in my model, but it seem not working.
My python version : 3.7.6 and django version : 3.0.0
ImproperlyConfigured at /add/
No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.
My View
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView
from .models import Page
class PageListView(ListView):
model = Page
template_name='home.html'
context_object_name = 'all_post_list'
class PageDetailView(DetailView):
model = Page
template_name='post.html'
class PageCreateView(CreateView):
model = Page
template_name='post_new.html'
fields = ['title', 'author', 'body', 'body2']
Model
from django.urls import reverse
from django.db import models
from ckeditor.fields import RichTextField
class Page(models.Model):
title = models.CharField(max_length=50)
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
)
body = RichTextField()
body2 = models.TextField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', args=[str(self.id)])
URL
from django.urls import path
from .views import PageListView, PageDetailView, PageCreateView
urlpatterns = [
path('add/', PageCreateView.as_view(), name='post_new'),
path('', PageListView.as_view(), name='home'),
path('blog/<int:pk>/', PageDetailView.as_view(), name='post'),
]
Thanks for helping. :)
I think your indentation is the problem here. Fix it by:
class Page(models.Model):
title = models.CharField(max_length=50)
author = models.ForeignKey(
'auth.User',
on_delete=models.CASCADE,
)
body = RichTextField()
body2 = models.TextField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post', args=[self.id])
I am using the Django REST Framework toolkit with Django 1.11 and I am trying to filter the results against the url. Here is my setup:
models.py:
from django.db import models
class Package(models.Model):
name = models.CharField(max_length=255, unique=True)
def __str__(self):
return self.name
serializers.py:
from rest_framework import serializers
from .models import Package
class PackageSerializer(serializers.ModelSerializer):
class Meta:
model = Package
fields = ('name',)
views.py:
from rest_framework import viewsets
from .models import Package
from .serializers import PackageSerializer
class PackageViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = PackageSerializer
queryset = Package.objects.all()
urls.py
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'package', views.PackageViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/v1/', include(router.urls)),
]
Currently when I use this I can filter the results by the id field:
http://127.0.0.1:8000/api/v1/package/1/
I am hoping to filter the results by the name field of my package model instead by using this:
http://127.0.0.1:8000/api/v1/package/basic/
How would I be able to accomplish this?
Set the lookup_field attribute in the viewset, see the documentation.
class PackageViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = PackageSerializer
queryset = Package.objects.all()
lookup_field = 'name'
Use filter_fields in views.
filter_fields = ('name',)
lookup field is used to set lookup by default it would be model pk
if you wish to make your URL,
my_url/filter_field/
set lookup_field = "name"
if you want search from URL like ,
my_url/?name=something
you need to set filter_fields in views.