Models.py
from django.db import models
# Create your models here.
class reviewData(models.Model):
building_name = models.CharField(max_length=50)
review_content = models.TextField()
star_num = models.FloatField()
class buildingData(models.Model):
building_name = models.CharField(max_length=50)
building_loc = models.CharField(max_length=50)
building_call = models.CharField(max_length=20)
views.py
# Create your views here.
from django.shortcuts import render
from rest_framework.response import Response
from .models import reviewData
from .models import buildingData
from rest_framework.views import APIView
from .serializers import ReviewSerializer
class BuildingInfoAPI(APIView):
def get(request):
queryset = buildingData.objects.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
class ReviewListAPI(APIView):
def get(request):
queryset = reviewData.objects.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
urls.py
from django.contrib import admin
from django.urls import path
from crawling_data.views import ReviewListAPI
from crawling_data.views import BuildingInfoAPI
urlpatterns = [
path('admin/', admin.site.urls),
path('api/buildingdata/', BuildingInfoAPI.as_view()),
#path('api/buildingdata/(I want to put building name here)', ReviewListAPI.as_view())
]
I am making review api.
I want to use building name as url path to bring reviews for specific buildings
For example, there are a, b, c reviews
a, b reviews are for aaabuilding
c reviews are for xxxbuilding
api/buildingdata/aaabuilding (only shows aaabuilding review)
{
building_name = aaabuilding
review_content = a
star_num = 5
building_name = aaabuilding
review_content = b
star_num = 3
}
api/buildingdata/xxxbuilding (only shows xxxbuilding review)
{
building_name = xxxbuilding
review_content = c
star_num = 4
}
I've searched some dynamic url posts, but they were not that i want.
Is there any way to bring building name into url from db?
In urls.py
path('api/buildingdata/<str:building>/', BuildingInfoAPI.as_view()),
And in views.py
class BuildingInfoAPI(APIView):
def get(request, building):
queryset = buildingData.objects.filter(building_name__contains=building)
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
Hope this will solve the issue
I suggets you take a look at the django documentation, this is pretty well explained there, here is a useful link
In your urls.py, you should put:
from django.contrib import admin
from django.urls import path
from crawling_data.views import ReviewListAPI
from crawling_data.views import BuildingInfoAPI
urlpatterns = [
path('admin/', admin.site.urls),
path('api/buildingdata/', BuildingInfoAPI.as_view()),
# added <str:building> to url
path('api/buildingdata/<str:building>', ReviewListAPI.as_view())
]
And in your views.py:
# Create your views here.
from django.shortcuts import render
from rest_framework.response import Response
from .models import reviewData
from .models import buildingData
from rest_framework.views import APIView
from .serializers import ReviewSerializer
class BuildingInfoAPI(APIView):
def get(request):
queryset = buildingData.objects.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
class ReviewListAPI(APIView):
# added another argument, retrieved from url
def get(request, building):
# changed .all() to .filter()
queryset = reviewData.objects.filter(building_name = building)
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
Related
I am trying to make a dynamic search but cant seem to filter queryset by slug. I have tried just about everything and went through stackoverflow questions and nothing seems to solve it. I have tried changing the keyword to "id" and "category" and I get a result but not on slug.
Here is the error/no queryset I received.
This is the filter I made for authors which seems to work.
Here is the code, Please inform if I need to provide more code to understand the problem as this is my first question here. Thanks!
blog_api/views.py
from rest_framework import generics
from blog.models import Post
from .serializers import PostSerializer
from rest_framework.permissions import SAFE_METHODS, IsAuthenticated, IsAuthenticatedOrReadOnly, BasePermission, IsAdminUser, DjangoModelPermissions
from rest_framework import viewsets
from rest_framework import filters
from django.shortcuts import get_object_or_404
from rest_framework.response import Response
class PostUserWritePermission(BasePermission):
message = 'Editing posts is restricted to the author only.'
def has_object_permission(self, request, view, obj):
if request.method in SAFE_METHODS:
return True
return obj.author == request.user
class PostList(generics.ListAPIView):
permission_classes = [IsAuthenticated]
# queryset = Post.objects.all()
serializer_class = PostSerializer
def get_queryset(self):
user = self.request.user
return Post.objects.filter(author=user)
class PostDetail(generics.RetrieveAPIView, PostUserWritePermission):
# permission_classes = [PostUserWritePermission]
queryset = Post.objects.all()
serializer_class = PostSerializer
def get_queryset(self):
item = self.kwargs["pk"]
print(item)
return Post.objects.filter(slug=item)
blog_api/urls.py
from .views import PostList, PostDetail
from django.urls import path
from rest_framework.routers import DefaultRouter
app_name = 'blog_api'
# router = DefaultRouter()
# router.register('', PostList, basename='post')
# urlpatterns = router.urls
urlpatterns = [
path('posts/<str:pk>/', PostDetail.as_view(), name='detail_create'),
path('', PostList.as_view(), name='list_create'),
]
blog/models.py
from django.db import models
from django.conf import settings
from django.utils import timezone
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Post(models.Model):
class PostObjects(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(status="published")
options = (
("draft", "Draft"),
("published", "Published"),
)
category = models.ForeignKey(Category, on_delete=models.PROTECT, default=1)
title = models.CharField(max_length=250)
excerpt = models.TextField(null=True)
content = models.TextField()
slug = models.SlugField(max_length=250, unique_for_date="published")
published = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="blog_post")
status = models.CharField(max_length=10, choices=options, default="published")
objects = models.Manager()
post_objects = PostObjects()
class Meta:
ordering = ["-published"]
def __str__(self):
return self.title
in your PostDetail class in blog_api/views.py file, instead of overriding get_queryset method, override get_object method, like this
def get_object(self, queryset=None, **kwargs):
item = self.kwargs.get('pk')
return get_object_or_404(Post.objects.filter(slug=item))
I'm a beginner in python-django coding. Currently I am trying to complete the challenge on https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Authentication but I am facing
LoanedBooksByAllUserListView is missing the permission_required attribute. Define LoanedBooksByAllUserListView.permission_required, or override LoanedBooksByAllUserListView.get_permission_required().
In urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('books/', views.BookListView.as_view(), name='books'),
path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail'),
path('authors/', views.AuthorListView.as_view(), name='authors'),
path('author/<int:pk>', views.AuthorDetailView.as_view(), name='author-detail'),
path('mybooks/', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'),
path('borrowed/', views.LoanedBooksByAllUserListView.as_view(), name='all-borrowed'),
]
In views.py
from django.shortcuts import render
# Create your views here.
from .models import Book, Author, BookInstance, Genre
def index(request):
"""View function for home page of site."""
# Generate counts of some of the main objects
num_books = Book.objects.all().count()
num_instances = BookInstance.objects.all().count()
# Available books (status = 'a')
num_instances_available = BookInstance.objects.filter(status__exact='a').count()
# The 'all()' is implied by default.
num_authors = Author.objects.count()
# Number of visits to this view, as counted in the session variable.
num_visits = request.session.get('num_visits', 0)
request.session['num_visits'] = num_visits + 1
context = {
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
'num_visits': num_visits,
}
# Render the HTML template index.html with the data in the context variable.
return render(request, 'index.html', context=context)
from django.views import generic
class BookListView(generic.ListView):
model = Book
paginate_by = 5
class BookDetailView(generic.DetailView):
model = Book
class AuthorListView(generic.ListView):
model = Author
paginate_by = 5
class AuthorDetailView(generic.DetailView):
model = Author
from django.contrib.auth.mixins import LoginRequiredMixin
class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView):
"""Generic class-based view listing books on loan to current user."""
model = BookInstance
template_name ='catalog/bookinstance_list_borrowed_user.html'
paginate_by = 10
def get_queryset(self):
return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')
from django.contrib.auth.mixins import PermissionRequiredMixin
class LoanedBooksByAllUserListView(PermissionRequiredMixin,generic.ListView):
model = BookInstance
template_name ='catalog/allbookinstancelistborrowed.html'
paginate_by = 10
def get_queryset(self):
return BookInstance.objects.filter(status__exact='o').order_by('due_back')
i am building a blog in Django and where register user can write blog articles . I want to display posts that are associated with certain categories on one page. i tried to do that but it does not show the post associated to the article. here is my files
models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from datetime import datetime, date
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
def get_absolute_url(self):
# return reverse('article', args=(str(self.id)))
return reverse('home') # go to home page after article submission
class Post(models.Model):
title = models.CharField(max_length=255)
tags = models.CharField(max_length=255, default="Ryan's World")
author = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
post_date = models.DateField(auto_now_add=True)
category = models.CharField(max_length=255, default="uncategorized")
def __str__(self):
return self.title+' | '+str(self.author)
def get_absolute_url(self):
# return reverse('article', args=(str(self.id)))
return reverse('home') # go to home page after article submission
views.py
created function based view
from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from .models import Post, Category
from .forms import PostForm, EditForm
from django.urls import reverse_lazy
class HomeView(ListView):
model = Post
template_name = 'home.html'
ordering = ['-id']
def CategoryView(request, cats):
category_posts = Post.objects.filter(category=cats)
return render(request, 'categories.html', {'cats':cats ,'category_posts': category_posts })
. . .
urls.py
from django.urls import path
# from . import views
from .views import HomeView, ArticleDetailView, AddPostView, UpdatePostView, DeletePostView, AddCategoryView, CategoryView
urlpatterns = [
# path('', views.home , name='home'),
path('', HomeView.as_view(), name="home"),
path('article/<int:pk>', ArticleDetailView.as_view(), name="article"),
path('add_post/', AddPostView.as_view(), name='add_post'),
path('add_category/', AddCategoryView.as_view(), name='add_category'),
path('article/edit/<int:pk>', UpdatePostView.as_view(), name="updatearticle"),
path('article/<int:pk>/remove', DeletePostView.as_view(), name="deletearticle"),
path('category/<str:cats>/', CategoryView, name='category')
]
forms.py
from django import forms
from .models import Post, Category
choices = Category.objects.all().values_list('name','name')
choice_list = []
for item in choices:
choice_list.append(item)
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'tags', 'author','category' ,'body')
widgets = {
'title': forms.TextInput(attrs={'class':'form-control', 'placeholder': 'this is placeholder'}),
'tags': forms.TextInput(attrs={'class':'form-control'}),
'author': forms.Select(attrs={'class':'form-control'}),
'category': forms.Select( choices = choice_list, attrs={'class':'form-control'}),
'body': forms.Textarea(attrs={'class':'form-control'}),
}
I am new in Django and python. Now I am trying to do web API with Django and python. I can get the get request but when I request the post method, this error is shown
"non_field_errors": [
"No data provided"
]
View.py=>
from rest_framework.generics import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Allowance
from .serializers import AllowanceSerializer
# Create your views here.
class AllowanceAPIView(APIView):
def get(self,request,pk=None):
if pk:
allowance=get_object_or_404(Allowance.objects.all(),pk=pk)
serializer = AllowanceSerializer(allowance)
return Response({serializer.data})
allowance=Allowance.objects.all()
serializer = AllowanceSerializer(allowance,many=True)
return Response({"allowance":serializer.data})
def post(self,request):
allowance = request.data.get('allowance')
serializer = AllowanceSerializer(data=allowance)
if serializer.is_valid(raise_exception=True):
allowance_saved=serializer.save()
return Response({"success":"Allowance '{}' created successfully".format(allowance_saved.AllowID)})
def put(self,request,pk):
save_allowance = get_object_or_404(Allowance.objects.all(),pk=pk)
data = request.data.get('allowance')
serializer = AllowanceSerializer(instance=save_allowance,data=data,partial=True)
if serializer.is_valid(raise_exception = True):
allowance_saved=serializer.save()
return Response({"sucess": "Allowance '{}' updated successfully".format(allowance_saved.AllowID)})
def delete(self,request,pk):
#Get object with this pk
allowance = get_object_or_404(Allowance.objects.all(),pk=pk)
allowance.delete()
return Response({"message":"Allowance with id '{}' has been deleted.".format(pk)},status=204)
urls.py inside app =>
from django.conf.urls import url
from .views import AllowanceAPIView
urlpatterns = [
url(r'^$', AllowanceAPIView.as_view(), name='post-listcreate'),
url(r'^(?P<pk>\d+)/$', AllowanceAPIView.as_view(), name='post-listcreate')
]
urls.py inside project =>
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
url(r'^admin/', admin.site.urls),
# url(r'^api/auth/login/$', obtain_jwt_token, name='api-login'),
url(r'^api/allowances_mas/', include('tmswebapi.urls')),
]
sample API request=>
{
"AllowID": "Allow1",
"AllowDesc": "Allow1 Description",
"AllowAmt": "11.00",
"AllowType": "MEAL",
"Created_DT": "2019-06-18T18:09:00Z",
"Created_Usr": "Admin",
"LastModified_Usr": "",
"LastModified_DT": "2019-06-18T18:09:00Z"
}
Serializer =>
from rest_framework import serializers
import datetime
from .models import Allowance
class AllowanceSerializer(serializers.ModelSerializer):
class Meta:
model=Allowance
fields = "__all__"
def create(self,validated_data):
return Allowance.objects.create(**validated_data)
def update(self,instance,calidated_data):
instance.AllowDesc = validated_data.get('AllowDesc',instance.AllowDesc)
instance.AllowAmt = validated_data.get('AllowAmt',instance.AllowAmt)
instance.AllowType = validated_data.get('AllowType',instance.AllowType)
instance.LastModified_Usr = "Admin"
instance.LastModified_DT = datetime.datetime.now()
instance.save()
return instance
Is it because of urls or because of data format?
It's returning error from on of if serializer.is_valid(raise_exception = True): lines.
It means data is None somewhere.
Debug your code to make sure data variable has data
def post(self,request):
allowance = request.data
serializer = AllowanceSerializer(data=allowance)
if serializer.is_valid(raise_exception=True):
allowance_saved=serializer.save()
return Response({"success":"Allowance '{}' created successfully".format(allowance_saved.AllowID)})
Now try this
I have a django model that looks like this:
class AcademicProgramsManager(models.Manager):
def get_by_natural_key(self, acad_program_id, program_title, required_credits):
return self.get(acad_program_id = acad_program_id, program_title = program_title, required_credits = required_credits)
class AcademicPrograms(models.Model):
objects = AcademicProgramsManager()
acad_program_id = models.IntegerField(primary_key=True)
acad_program_category = models.ForeignKey(AcademicProgramCategories)
acad_program_type = models.ForeignKey(AcademicProgramTypes)
acad_program_code = models.CharField(max_length=25)
program_title = models.CharField(max_length=64)
required_credits = models.IntegerField()
min_gpa = models.FloatField()
description = models.CharField(max_length=1000)
def natural_key(self):
return (self.acad_program_id, self.program_title, self.required_credits)
class StudentAcademicPrograms(models.Model):
student = models.ForeignKey(Students)
academic_program = models.ForeignKey(AcademicPrograms)
credits_completed = models.IntegerField()
academic_program_gpa = models.FloatField()
primary_program = models.BooleanField()
This is my serializers.py file:
from studentapp.models import AcademicPrograms, AcademicProgramsManager, StudentAcademicPrograms
from rest_framework import serializers
class StudentAcademicProgramsSerializer(serializers.ModelSerializer):
class Meta:
model = StudentAcademicPrograms
fields = ('credits_completed','academic_program_gpa','primary_program')
class AcademicProgramsSerializer(serializers.ModelSerializer):
studentacademicprograms = StudentAcademicProgramsSerializer(many = True)
class Meta:
model = AcademicPrograms
fields = ('acad_program_id','program_title','required_credits','studentacademicprograms')
My api.py file looks like this:
from studentapp.models import AcademicPrograms, AcademicProgramsManager, StudentAcademicPrograms
from studentapp.serializers import StudentAcademicProgramsSerializer, AcademicProgramsSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
class AcademicProgramsList(APIView):
def get(self, request, format=None):
academicprograms = AcademicPrograms.objects.all()
serialized_academicprograms = AcademicProgramsSerializer(academicprograms, many=True)
return Response(serialized_academicprograms.data)
class AcademicProgramsDetail(APIView):
def get_onjects(self, pk):
try:
return AcademicPrograms.object.get(pk=pk)
except AcademicPrograms.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
academicprogram = self.get_object(pk)
serialized_academicprogram = AcademicProgramsSerializer(academicprogram)
return Response(serialized_academicprogram.data)
and finally my urls:
from django.conf.urls import patterns, include, url
from rest_framework.urlpatterns import format_suffix_patterns
from studentapp import api
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'texascompletes.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
#API:
url(r'^api/studentacademicprograms/$', api.AcademicProgramsList.as_view()),
url(r'^api/studentacademicprograms/(?P<pk>[0-9]+)/$', api.AcademicProgramsDetail.as_view()),
url(r'^admin/', include(admin.site.urls)),
)
urlpatterns = format_suffix_patterns(urlpatterns)
I am getting the following error when i give my api/studentacademicprograms
'AcademicPrograms' object has no attribute 'studentacademicprograms'
Where am i going wrong?
Try setting the source to the attribute/method name on the model. For example:
studentacademicprograms = StudentAcademicProgramsSerializer(
many=True,
source='studentacademicprograms_set')
The example given in the Django Rest Framework Serializer relations docs sets a related name on the models which matches the attribute name in the serializer (the default). If the names don't match you need to specify them model's source method/attribute to use.