How Do I get a URL parameter passed into a django CBV? - django

I have a urls.py file setup as follows
from django.conf.urls import patterns, include, url
from .views import *
urlpatterns = patterns('',
url(r'^$', BlogListView.as_view()),
url(r'(?P<blog_id>)\d{1,}/$', BlogDetailView.as_view())
)
with the correlating view
class BlogDetailView(View):
def get(self, request, blog_id, *args, **kwargs):
post = Blog.objects.get(post_id=blog_id).to_detail_json
return HttpResponse(json.dumps(post), mimetype='application/json')
I get an error when I visit 127.0.0.1:8000/blog/1/
ValueError at /blog/4/
invalid literal for int() with base 10: ''
but if I change
post = Blog.objects.get(post_id=blog_id).to_detail_json
to
post = Blog.objects.get(post_id=1).to_detail_json
then I get the correct response.
In case it is wanted, here is my model
from mongoengine import *
from collections import OrderedDict
import datetime
import json
class Blog(Document):
post_id = IntField(unique=True)
title = StringField(max_length=144, required=True)
date_created = DateTimeField(default=datetime.datetime.now)
body = StringField(required=True)
def __init__(self, *args, **kwargs):
self.schema = {
"title": self.title,
"date": str(self.date_created),
"id": self.post_id,
"body": self.body
}
super(Blog, self).__init__(*args, **kwargs)
#property
def to_detail_json(self):
fields = ["id","title", "date", "body"]
return {key:self.schema[key] for key in fields}
#property
def to_list_json(self):
fields = ["title", "date"]
return {key:self.schema[key] for key in fields}
Update
I changed the BlogDetailView to return
return HttpResponse(json.dumps(self.kwargs),mimetype='application/json')
and it gives me
{
blog_id: ""
}
Which leads me to believe it is something with my urls.py file, but I do not see the error.

try
post = Blog.objects.get(post_id=self.kwargs['blog_id']).to_detail_json

It turns out that
url(r'(?P<blog_id>)\d{1,}/$', BlogDetailView.as_view())
should be
url(r'(?P<blog_id>\d{1,})/$', BlogDetailView.as_view())

Related

Reverse for 'Page' not found. 'Page' is not a valid view function or pattern name

this is the error I got when I wanted to create a dynamic sitemap.
sitemap.py
from django.contrib import sitemaps
from django.shortcuts import reverse
from django.utils import timezone
from django.contrib.sitemaps import Sitemap
#models
from home.models import Page
class StaticViewSitemap(sitemaps.Sitemap):
priority = 0.5
changefreq = "daily"
protocol = 'https'
def items(self):
return [
'home:about',
]
def location(self, item):
return reverse(item)
def lastmod(self, item):
return timezone.now()
class DynamicSitemap(Sitemap):
changefreq = "daily"
priority = 0.5
def items(self):
return Page.objects.all()
models.py
class Page(models.Model):
city = models.CharField(max_length=40, verbose_name="Şehir")
seo = models.CharField(max_length=50, verbose_name="Seo")
def __str__(self):
return self.city
def get_absolute_url(self):
return reverse('home:page', kwargs={'pk': self.pk})
home/urls.py:
app_name = "home"
urlpatterns = [
# ⋮,
path(r'page/<int:pk>', views.yardimsayfalari, name="page"),
# ⋮,
]
static sitemap works fine but dynamic sitemap I get the same error. Thank you to those who are interested so far.
I'm sorry for my bad english
Based on the get_absolute_url, you try to link this to:
path(r'page', views.yardimsayfalari, name='page'),
The name of your view is page, not Page. Furthermore you specified app_name = 'home', hence full name of the view is home:page. Finally your path does not contain any parameter, so args=(self.pk,) makes not much sense.
You thus likely should include a primary key parameter:
app_name = "home"
urlpatterns = [
# &vellip;,
path('page/<int:pk>/', views.yardimsayfalari, name="page"),
# &vellip;,
]
include that pk parameter in your view:
def yardimsayfalari(request, pk):
# …
# return HTTP response
and finally refer to the view with:
class Page(models.Model):
# &vellip;
def get_absolute_url(self):
return reverse('home:page', args=(self.pk,))
It might also make more sense to work with a named parameter, so:
class Page(models.Model):
# &vellip;
def get_absolute_url(self):
return reverse('home:page', kwargs={'pk': self.pk})
based on this, I would advise to (re)read the third part of the Django tutorial.

ValueError - The view didn't return an HttpResponse object. It returned None instead

My view currently returns an error of
The view viajecenter.views.receive_payment didn't return an
HttpResponse object. It returned None instead.
I tried some of the solutions from other related posts here but of no luck.
Here is my function in my views.py file:
def receive_payment(request, account_code):
template_name = 'receive-payment.html'
user = request.user
account = get_object_or_404(Account, account_code=account_code)
if user.is_assigned:
puv = Puv.objects.get(assignment_id=user.assignment_id)
locations = puv.route.locations.all().order_by('distance_from_base')
context = {
'account': account,
'puv': puv,
'locations': locations,
}
return render(request, template_name, context)
else:
return user
and the corresponding url in urls.py file:
from django.urls import path
from . views import ..., receive_payment
urlpatterns = [
...
path('receive-payment/<str:account_code>', receive_payment, name="receive-payment"),
]
and my Account model:
class Account(AbstractBaseUser, PermissionsMixin):
...
account_code = models.UUIDField(default=uuid.uuid4, editable=False)
is_assigned = models.BooleanField(default=False)
Thank you for lending me your time and answering my question :)
It seems you're trying to mix and match function-based views and class-based views.
You can rewrite your view as a DetailView class-based view like so:
from django.views.generic import DetailView
class ReceivePaymentView(DetailView):
template_name = "receive-payment.html"
model = Account
slug_url_kwarg = "account_code"
slug_field = "account_code"
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
account = context["object"]
user = self.request.user
if user.is_assigned:
puv = Puv.objects.get(assignment_id=user.assignment_id)
locations = puv.route.locations.all().order_by("distance_from_base")
context["account"] = account
context["puv"] = puv
context["locations"] = locations
return context
urlpatterns = [
path('receive-payment/<account_code>', ReceivePaymentView.as_view(), name="receive-payment"),
]

DJANGO: mixins.DestroyModelMixin delete - method not allowed

I have an API that returns list of all likes.
Here is model for likes:
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True)
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'post'], name='like_once')
]
Here is my view:
class likeList(mixins.CreateModelMixin, mixins.DestroyModelMixin, generics.ListAPIView):
serializer_class = likeserializers
def get_queryset(self):
return Like.objects.all()
def post(self, request, *args, **kwargs):
try:
return self.create(request, *args, **kwargs)
except IntegrityError:
content = {'error': 'IntegrityError'}
return Response(content, status=status.HTTP_400_BAD_REQUEST)
def destroy(self, request, *args, **kwargs):
try:
return self.destroy(request, *args, **kwargs)
except IntegrityError:
content = {'error': 'IntegrityError'}
return Response(content, status=status.HTTP_400_BAD_REQUEST)
Here are my urls:
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path
from . import views as API_views
urlpatterns = [
path('users/', API_views.userList.as_view(), name = 'users'),
path('users/id=<int:id>/', API_views.userListbyID.as_view(), name = 'usersid'),
path('posts/', API_views.postList.as_view(), name = 'post'),
path('posts/id=<int:id>', API_views.postListbyID.as_view(), name = 'postid'),
path('likes/', API_views.likeList.as_view(), name = 'likes'),
path('likes/test/<int:id>', API_views.likeListbyID.as_view(), name = 'likesid'),
path('likes/<int:id>', API_views.LikeCountView.as_view(), name='likecount'),
path('follows/', API_views.followList.as_view(), name = 'follows'),
path('follows/id=<int:id>', API_views.followListbyID.as_view(), name = 'followsid'),
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.MEDIA_URL)
I call the delete api with json body {"user":userid,"post":postid}
however, I receive method Not Allowd (HTTP 405). Also I can see on the API page "Allow: GET, POST, HEAD, OPTIONS"
What am I doing wrong?
FYI: The get and create methods work as expected.
You need to use two different views for these operations. List and Create mixins do not require object pk but Destroy mixin does. You need to split Destroy mixin to another view as sampled in docs. If you do not supply pk to delete, the operation fails.

How do I combine multiple models into a single serializer?

it was necessary to combine several models(4) in one serializer, but there were problems with the implementation.
urls.py
from django.urls import path
from .views import FiltersView
urlpatterns = [
path('filters/' FiltersView.as_view(), name='Filters')
]
views.py
from rest_framework import views
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK
from .serializers import FiltersSerializers
class FiltersView(views.APIView):
def get(self, request, *args, **kwargs):
filters = {}
filters['model_1'] = Model1.objects.all()
filters['model_2'] = Model2.objects.all()
filters['model_3'] = Model3.objects.all()
serializer = FiltersSerializers(filters, many=True)
return Response (serializer.data, status=HTTP_200_OK)
serializers.py
from rest_framework import serializers
class FiltersSerializers(serializers.Serializer):
model_1 = Model1Serializers(read_only=True, many=True)
model_2 = Model2Serializers(read_only=True)
model_3 = Model3Serializers(read_only=True)
But on the output I get:
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{},
{},
{}
]
What could be the problem?
The way you are providing data to your serializer, many=True is not correct argument for it. Its a single object that you are passing to your serializer. Your view should be like this.
class FiltersView(views.APIView):
def get(self, request, *args, **kwargs):
filters = {}
filters['model_1'] = Model1.objects.all()
filters['model_2'] = Model2.objects.all()
filters['model_3'] = Model3.objects.all()
serializer = FiltersSerializers(filters)
return Response (serializer.data, status=HTTP_200_OK)

Error:Page not found (404) after runserver

I have an django app,But i want to make its API so just i created it
after runing the server
Page not found (404)
But my django app is running,After the running the url of API i got the error of Page not found
List/views.py
from django.http import Http404
from django.shortcuts import render
from django.views.generic import ListView,DetailView
from .models import List
from django.http import HttpResponse,JsonResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from List.serializers import ListSerializers
class MainListView(ListView):
queryset = List.objects.all()
# temp = List.objects.all()
template_name = "main_list.html"
def get_context_data(self, *args, **kwargs):
context = super(MainListView, self).get_context_data(*args, **kwargs)
context['temp'] = List.objects.all()
return context
class MainListView(ListView):
queryset = List.objects.all()
# temp = List.objects.all()
template_name = "List/list.html"
def get_context_data(self, *args, **kwargs):
context = super(MainListView, self).get_context_data(*args, **kwargs)
context['temp'] = List.objects.all()
return context
class MainDetailSlugView(DetailView):
queryset = List.objects.all()
template_name = "news/detail.html"
#csrf_exempt
def head_list(request):
if request.method == 'GET':
queryset = List.objects.all()
serializer = ListSerializer(queryset, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = ListSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
#csrf_exempt
def head_detail(request, pk):
try:
head = List.objects.get(pk=pk)
except List.DoesNotExist:
return HttpResponse(status=404)
if request.method == 'GET':
serializer = ListSerializer(list)
return JsonResponse(serializer.data)
elif request.method == 'PUT':
data = JSONParser().parse(request)
serializer = SnippetSerializer(head, data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status=400)
elif request.method == 'DELETE':
head.delete()
return HttpResponse(status=204)
List/urls.py
from django.urls import path
from List import views
from .views import(
# ListlistView,
MainListView,
MainDetailSlugView,
head_list,
head_detail
)
urlpatterns = [
# url(r'^$',ListlistView.as_view()),
path('',MainListView.as_view(),name='list'),
path('(<pk>\d+)(?:/(<slug>[\w\d-]+))',MainDetailSlugView.as_view(), name='List'),
path('list/',views.list_list),
path('lists/<int:pk>/',views.list_detail),
]
List/serializers.py
from rest_framework import serializers
from List.models import List
class ListSerializers(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(required=True, allow_blank=False,max_length=120)
slug = serializers.SlugField(required=False,)
description= serializers.CharField(required=True, allow_blank=False)
image = serializers.ImageField(required=True,)
timestamp = serializers.DateTimeField(required=True,)
code = serializers.CharField(style={'base_template': 'textarea.html'})
language = serializers.CharField(default='python')
style = serializers.CharField(default='friendly')
def create(self, validated_data):
return List.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.descritption = validated_data.get('descritption', instance.descritption)
instance.image = validated_data.get('image', instance.image)
instance.timestamp = validated_data.get('timestamp',instance.timestamp)
instance.language = validated_data.get('language',instance.language)
instance.style = validated_data.get('style',)
instance.save()
return instance
List/models.py
import random
import os
from django.db import models
from django.urls import reverse
from django.db.models.signals import pre_save, post_save
from lokswar.utils import unique_slug_generator
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0],item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item,item) for item in get_all_styles())
def get_filename_ext(filepath):
base_name = os.path.basename(filepath)
name, ext = os.path.splitext(base_name)
return name,ext
def upload_image_path(instence, filename):
new_filename = random.randint(1,396548799)
name, ext = get_filename_ext(filename)
final_filename = '{new_filename}{ext}'.format(new_filename=new_filename, ext= ext)
return "card/{new_filename}/{final_filename}".format(new_filename=new_filename,
final_filename=final_filename)
class ListQuerySet(models.query.QuerySet):
def active(self):
return self.filter(active=True)
class ListManager(models.Manager):
def get_queryset(self):
return ListQuerySet(self.model, using=self._db)
def all(self):
return self.get_queryset().active()
class List(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=120)
slug = models.SlugField(blank=True, unique=True)
description= models.TextField()
image = models.ImageField(upload_to=upload_image_path,null=True, blank=True)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True)
code = models.TextField(default=True)
language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
objects = ListManager()
class Meta:
ordering = ('created',)
def get_absolute_url(self):
return reverse('List', kwargs={'pk': self.pk, 'slug': self.slug })
def __str__(self):
return self.title
def __unicode__(self):
return self.title
Please help me to solve this error.
I am trying to run my API through this url http://127.0.0.1:8000/List/list/
urls.py
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
from .views import HomeListView
urlpatterns = [
path('List',include('List.urls'), name="List"),
path('news/',include('news.urls'), name="news"),
path('', HomeListView.as_view(), name='home'),
path('sports/',include('sports.urls'), name="sports"),
path('movie/',include('movie.urls'), name="movie"),
path('business/',include('business.urls'), name="business"),
path('api-auth/', include('rest_framework.urls')),
path('admin/', admin.site.urls),
]
You make a small mistake in url at url.py file.
Change:
path('List',include('List.urls'), name="List"),
Into:
path('List/',include('List.urls'), name="List"),
urlpatterns = [
path('',MainListView.as_view(),name='list'),
path('(<pk>\d+)(?:/(<slug>[\w\d-]+))',MainDetailSlugView.as_view(), name='List'),
path('list/',views.list_list),
path('lists/<int:pk>/',views.list_detail),
]
As you can see above, you have two urls defined that apply here
/list/
/lists/<int> # which applies to something like /lists/293749
you're URL calling is /List/list, which doesn't apply to any URLs here unless you define a project-level URLs.py with something like
urlpatterns = [
path('list/', include('List.urls'))
]
Couple things:
Take a look at python conventions. Classes are capitalized and PascalCase whereas variables, methods and functions are snake_case. No reason for you to have a module capitalized
Don't use the same names as python/django builtins and reserved words. That causes issues and is a good habit to get into.
I believe django treats urls as case sensitive when they come in the URL parser. You call /List, but the url definition is /list