I am new to testing and am trying to run the following tests but I get a 404 assertion error because the method that tries to reverse the url cannot find the category that had been created in the setUp method. I can create categories in the browser using the superuser with no problem and the url responds with 200 status. Could you help me understand what I am doing wrong?
Test:
from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.contrib.auth.models import User
from cataloger.models import Category
class CatalogerCategoriesTests(TestCase):
def setUp(self):
tom = User.objects.create_user(username="tom", password="1234567")
Category.objects.create(name="cell phone",
description="current cell phone types in the market.",
created_by=tom)
def test_category_page_success_status_code(self):
url = reverse('category_items', kwargs={'pk': 1})
response = self.client.get(url)
self.assertEquals(response.status_code, 200)
Fail:
Traceback (most recent call last):
File "/home/ubuntu/workspace/cataloger/tests_categories.py", line 48, in test_category_page_success_status_code
self.assertEquals(response.status_code, 200)
AssertionError: 404 != 200
Models:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=50)
description = models.CharField(max_length=300)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
created_by = models.ForeignKey(User, related_name="categories")
Views:
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.models import User
from cataloger.models import Category
def category_items(request, pk):
category = get_object_or_404(Category, pk=pk)
return render(request, 'category_items.html', {'category': category})
urls:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^cataloger/$', views.cataloger, name='cataloger'),
url(r'^cataloger/categories/(?P<pk>\d+)/$', views.category_items, name='category_items')
]
The pk of the object might not always be 1 depending upon the test structure and DB. The pk of the Category instance should be used explicitly.
from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.contrib.auth.models import User
from cataloger.models import Category
class CatalogerCategoriesTests(TestCase):
def setUp(self):
tom = User.objects.create_user(username="tom", password="1234567")
self.category = Category.objects.create(
name="cell phone",
description="current cell phone types in the market.",
created_by=tom
)
def test_category_page_success_status_code(self):
url = reverse('category_items', kwargs={'pk': self.category.pk})
response = self.client.get(url)
self.assertEquals(response.status_code, 200)
#Stuart Dines explains very well. You should match pk for urls.
Or if you just want to know that model instance created well, just try self.assertIsInstance(...)
def setUp(self):
tom = User.objects.create_user(username="tom", password="1234567")
category = Category.objects.create(name="cell phone",
description="current cell phone types in the market.",
created_by=tom)
def test_if_category_instance_made(self):
self.assertIsInstance(self.category, Category)
Also I recommend model mommy for easy testing django models. It automatically generate random model (also put test data possible) and make really easy to testing your model!
This is example using model_mommy for your test code
from model_mommy import mommy
class CatalogerCategoriesTests(TestCase):
def setUp(self):
self.tom = mommy.make("User")
self.category = mommy.make("Category", user=self.user)
def test_if_category_instance_made(self):
self.assertIsInstance(self.category, Category)
def test_category_page_success_status_code(self):
url = reverse('category_items', kwargs={'pk': self.category.pk})
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
Related
I have a class-based view that returns all the data in the table. But while accessing the URL all I get is an empty list.
models.py
from django.db import models
class EmployeeModel(models.Model):
EmpID = models.IntegerField(primary_key=True)
EmpName = models.CharField(max_length=100)
Email = models.CharField(max_length=100)
Salary = models.FloatField()
class Meta:
verbose_name = 'employeetable'
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import EmployeeModel
from .serializers import EmployeeSerialize
class EmployeeTable(APIView):
def get(self,request):
emp_obj = EmployeeModel.objects.all()
empserializer = EmployeeSerialize(emp_obj,many=True)
return Response(empserializer.data)
serializers.py
from rest_framework import serializers
from .models import EmployeeModel
class EmployeeSerialize(serializers.ModelSerializer):
class Meta:
model = EmployeeModel
fields = '__all__'
urls.py
from django.contrib import admin
from django.urls import path, include
from .views import EmployeeTable, transformer_list
urlpatterns = [
path('display/',EmployeeTable.as_view()),
]
The table has 5 rows. It is not empty.
I want to serialize all 5 rows
I have also created the same but in my case, it worked see the below images
See my serializer
See my models below
and my output is here below
I think there are some issue at your code or some mistake can be there can you please provide full information
I recently started learning Django. I want to display one news item, but when I open on the link I get an error message:
Cannot resolve keyword 'slug' into field. Choices are: NewsTitles, NewsContent, NewsSlug
Request Method: GET
Request URL: http://127.0.0.1:8000/news/nam-gravida-purus-non/
Django Version: 4.0
Exception Type: FieldError
views.py
from django.views.generic import DetailView
from .models import News
class GetNews(DetailView):
model = News
slug_url_kwarg = 'NewsSlug'
template_name = 'news/single_news.html'
context_object_name = 'single_news'
allow_empty = False
urls.py
from django.urls import path
from .views import GetNews
urlpatterns = [
path('news/<str:NewsSlug>/', GetNews.as_view(), name='news'),
]
models.py
from django.db import models
from django.urls import reverse_lazy
class News(models.Model):
NewsTitles = models.CharField(max_length=120)
NewsContent = models.TextField(max_length=255)
NewsSlug = models.SlugField(max_length=255)
def __str__(self):
return self.NewsTitles
def get_absolute_url(self):
return reverse_lazy('news', kwargs={'NewsSlug': self.NewsSlug})
What am I doing wrong?
First of all do not call your slug "NewSlug" with uppercase but all lower case "newslug" or even better "new_slug", the name itself should be more descriptive as well.
Finally you need to tell your view which field to use, you can define that with the following attribute :
slug_field = "NewSlug"
Note : Attribute of a class should not be camel case but snake case
My code is:
from django.shortcuts import render # Create your views here.
from django.views.generic import ListView # <- new
from .models import Post
def home(request):
context = {
'posts': Post.objects.all()
}
return render(request, 'blog/home.html', context)
And the error I receive is
from .models import Post
Exception has occurred: ImportError
attempted relative import with no known parent package
Post is defined in:
from django.db import models # Create your model fields here.
from django.utils import timezone # for the DateTimeZone field below
from django.contrib.auth.models import User # the author field below needs this
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField() # TextField has no length limitation
date_posted = models.DateTimeField(default=timezone.now) # Use the django timezone
author = models.ForeignKey(User, on_delete=models.CASCADE) # if the User is deleted, so will this model
def __str__(self):
return self.title
Any help would be appreciated.
models.py:
from __future__ import unicode_literals
from django.db import models
class Photo(models.Model):
title = models.CharField(max_length=255, blank=True)
file = models.FileField()
uploaded_at = models.DateTimeField(auto_now_add=True)
serializers.py:
from rest_framework import serializers
from . models import Photo
class imageSerializer(serializers.ModelSerializer):
class Meta:
model = Photo
fields='__all__'
views.py:
from django.shortcuts import render,redirect
from django.http import JsonResponse
from django.views import View
import time
from rest_framework import generics
from .forms import PhotoForm
from .models import Photo
from django.http import HttpResponse
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework import status
from .serializers import imageSerializer
import requests
class DragAndDropUploadView(View):
def get(self, request):
photos_list = Photo.objects.all()
return render(self.request, 'UploadMulti/drag_and_drop_upload/index.html', {'photos': photos_list})
def post(self, request):
form = PhotoForm(self.request.POST, self.request.FILES)
if form.is_valid():
photo = form.save()
data = {'is_valid': True, 'name': photo.file.name, 'url': photo.file.url}
else:
data = {'is_valid': False}
return JsonResponse(data)
def clear_database(request):
for photo in Photo.objects.all():
photo.file.delete()
photo.delete()
return redirect(request.POST.get('next'))
class ImagesList(APIView):
def get(self,request):
imagelist=Photo.objects.all()
serializer = imageSerializer(imagelist,many=True)
return Response(serializer.data)
def post(self):
pass
def backend(request):
response = requests.get('http://localhost:8000/images/')
api_values = response.json()
for values in api_values:
print(type(values['file']))
return render(request,"home.html",{'data':api_values})
when I print type of values.file which is the image data I am getting as therefore when sending it to frontend the image is not displayed
How to retrieve as image file from rest api?
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"id": 1,
"title": "",
"file": "think-twice-code-once.jpg",
"uploaded_at": "2019-11-27T12:34:32.270786Z"
}
]
Is there any other method to obtain images from rest framework and whether the image is stored as Image format ?
The issue is due to your configuration of FileField for this particular serializer. You need use_url to be True. So you can either change the UPLOADED_FILES_USE_URL setting or set use_url=True in imageSerializer as seen below.
class imageSerializer(serializers.ModelSerializer):
class Meta:
model = Photo
fields='__all__'
file = serializers.FileField(use_url=True)
Side note, imageSerializer should really be ImageSerializer to follow the python class naming guidelines.
I am using Django Signals to Trigger Code once the user is created i am saving additional data on another model class, it's getting triggered but it's not redirecting to additional data object page.
Here is my models.py
from django.db import models
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class Customers(models.Model):
user = models.OneToOneField(User)
business_name = models.CharField(max_length=250)
address = models.CharField(max_length=500)
area = models.CharField(max_length=250)
city = models.CharField(max_length=250)
state = models.CharField(max_length=250)
pincode = models.IntegerField(default='0')
phone = models.IntegerField(default='0')
mobile = models.IntegerField(default='0')
def create_customer(sender, **kwargs):
if kwargs['created']:
customer_profile = Customers.objects.create(user=kwargs['instance'])
post_save.connect(create_customer, sender=User)
and here is my admin.py
from django.contrib import admin
from .models import Customers
from django.shortcuts import redirect
admin.site.register(Customers)
class Customers(admin.ModelAdmin):
def response_add(self, request, obj, post_url_continue=None):
return redirect('/admin/app/customers/add/')
def response_change(request, obj):
return redirect('/admin/app/customers/add/')
Tired looking for the answer but nothing works, please correct me here.
It doesn't look like you are registering your admin configuration. Refer to Django docs on the register decorator for more information. The syntax is to decorate your function with #admin.register(<model>) or if you want to manually register the model admin configuration then admin.site.register(<model>, <model admin>).
I would recommend changing class Customers(admin.ModelAdmin): to class CustomersAdmin(admin.ModelAdmin): or something similar to stop the namespace clash.
See example below:
from django.contrib import admin
from .models import Customers
from django.shortcuts import redirect
#admin.register(Customers)
class CustomersAdmin(admin.ModelAdmin):
def response_add(self, request, obj, post_url_continue=None):
return redirect('/admin/app/customers/add/')
def response_change(request, obj):
return redirect('/admin/app/customers/add/')