3

Working on hellowebapp.com

Please help test valid form post using Django test client post request?

response = self.client.post('/accounts/create_thing/', { 'name': dummy_thing.name, 'description': dummy_thing.description, })

Here's the TestCase Code Snippet:

from django.test import TestCase, RequestFactory   
from django.contrib.auth.models import AnonymousUser, User
from collection.models import Thing
from .views import *
from collection.forms import ThingForm

class SampleTest(TestCase):
    def setUp(self):
        # Every test needs access to the request factory.
        self.factory = RequestFactory()
        self.dummy_user = User.objects.create_user(username='dummy', password='nothings')
        self.dummy_thing = Thing.objects.create(name="Dummy Book",
                                          description="Book For Dummies.",
                                          slug="dummy-book",
                                          user=self.dummy_user)
    def test_form(self):
        dummy_thing = Thing.objects.get(name="Dummy Book")
        form = ThingForm(instance=dummy_thing)
        self.assertFalse(form.is_valid()) # No data has been supplied yet.
        form = ThingForm({ 'name': dummy_thing.name, 'description': dummy_thing.description, }, instance=dummy_thing)
        self.assertTrue(form.is_valid())

    def test_form_post(self):
        dummy_thing = Thing.objects.get(name="Dummy Book")
        self.client.login(username=dummy_thing.user.username, password='nothings')

        # Test POST invalid data
        response = self.client.post('/accounts/create_thing/', { })
        self.assertFormError(response, 'form', 'name', 'This field is required.')
        self.assertFormError(response, 'form', 'description', 'This field is required.')
        self.assertTemplateUsed(response, 'things/create_thing.html')
        self.assertEqual(response.status_code, 200)

        # Test POST valid data? 
        # response = self.client.post('/accounts/create_thing/', { 'name': dummy_thing.name, 'description': dummy_thing.description, })
        # self.assertEqual(response.status_code, 200)

Here's the Model

models.py

class Thing(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    slug = models.SlugField(unique=True)
    user = models.OneToOneField(User, blank=True, null=True)

Note: user = models.OneToOneField(User, blank=True, null=True)

"Thing.user" must be a "User" instance.

column user_id is must be unique.

views.py

from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.shortcuts import render, redirect
from django.template.defaultfilters import slugify

from collection.forms import ThingForm
from collection.models import Thing


def index(request):
    things = Thing.objects.all()
    return render(request, 'index.html', {
        'things': things,
    })


def thing_detail(request, slug):
    # grab the object...
    thing = Thing.objects.get(slug=slug)

    # and pass to the template
    return render(request, 'things/thing_detail.html', {
        'thing': thing,
    })


@login_required
def edit_thing(request, slug):
    # grab the object...
    thing = Thing.objects.get(slug=slug)

    # grab the current logged in user and make sure they're the owner of the thing
    if thing.user != request.user:
        raise Http404

    # set the form we're using...
    form_class = ThingForm

    # if we're coming to this view from a submitted form,  
    if request.method == 'POST':
        # grab the data from the submitted form
        form = form_class(data=request.POST, instance=thing)

        if form.is_valid():
            # save the new data
            form.save()
            return redirect('thing_detail', slug=thing.slug)

    # otherwise just create the form
    else:
        form = form_class(instance=thing)

    # and render the template
    return render(request, 'things/edit_thing.html', {
        'thing': thing,
        'form': form,
    })


def create_thing(request):
    form_class = ThingForm

    # if we're coming from a submitted form, do this
    if request.method == 'POST':
        # grab the data from the submitted form and apply to the form
        form = form_class(request.POST)

        if form.is_valid():
            # create an instance but do not save yet
            thing = form.save(commit=False)

            # set the additional details
            thing.user = request.user
            thing.slug = slugify(thing.name)

            # save the object
            thing.save()

            # redirect to our newly created thing
            return redirect('thing_detail', slug=thing.slug)

    # otherwise just create the form
    else:
        form = form_class()

    return render(request, 'things/create_thing.html', {
        'form': form,
    })


def browse_by_name(request, initial=None):
    if initial:
        things = Thing.objects.filter(
             name__istartswith=initial).order_by('name')
    else:
        things = Thing.objects.all().order_by('name')

    return render(request, 'search/search.html', {
        'things': things,
        'initial': initial,
    })

Here's the error:

$ python manage.py test

.ECreating test database for alias 'default'...
Destroying test database for alias 'default'...

======================================================================
ERROR: test_form_post (collection.tests.SampleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "E:\Working\Python\Django\Python2.7\Hello-Web-App\GitHub\Test\hellowebapp-code-master\collection\tests.py", line 36, in test_form_post
    response = self.client.post('/accounts/create_thing/', { 'name': dummy_thing.name, 'description': dummy_thing.description, })
  File "C:\Python27\lib\site-packages\django\test\client.py", line 541, in post
    secure=secure, **extra)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 343, in post
    secure=secure, **extra)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 409, in generic
    return self.request(**r)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 494, in request
    six.reraise(*exc_info)
  File "C:\Python27\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
    response = get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\Working\Python\Django\Python2.7\Hello-Web-App\GitHub\Test\hellowebapp-code-master\collection\views.py", line 77, in create_thing
    thing.save()
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 796, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 824, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 908, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 947, in _do_insert
    using=using, raw=raw)
  File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Python27\lib\site-packages\django\db\models\query.py", line 1043, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 1054, in execute_sql
    cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py", line 337, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: column user_id is not unique

----------------------------------------------------------------------
Ran 2 tests in 0.687s

FAILED (errors=1)

Also, tried Django shell in vain:

$ winpty python manage.py shell
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec  5 2015, 20:40:30) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.test import Client
>>> csrf_client = Client(enforce_csrf_checks=True)
>>> c.login(username="dummy", password='nothings')
>>> c = Client()
>>> c.login(username="dummy", password='nothings')
True
>>> response = c.post('http://127.0.0.1:8000/accounts/create_thing/', { 'name': 'dummy book', 'description': 'book for dummies' })
Internal Server Error: /accounts/create_thing/
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
    response = get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\Working\Python\Django\Python2.7\Hello-Web-App\GitHub\Test\hellowebapp-code-master\collection\views.py", line 77, in create_thing
    thing.save()
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 796, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 824, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 908, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 947, in _do_insert
    using=using, raw=raw)
  File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Python27\lib\site-packages\django\db\models\query.py", line 1043, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 1054, in execute_sql
    cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py", line 337, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: column user_id is not unique
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "C:\Python27\lib\site-packages\django\test\client.py", line 541, in post
    secure=secure, **extra)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 343, in post
    secure=secure, **extra)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 409, in generic
    return self.request(**r)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 494, in request
    six.reraise(*exc_info)
  File "C:\Python27\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
    response = get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\Working\Python\Django\Python2.7\Hello-Web-App\GitHub\Test\hellowebapp-code-master\collection\views.py", line 77, in create_thing
    thing.save()
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 796, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 824, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 908, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 947, in _do_insert
    using=using, raw=raw)
  File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Python27\lib\site-packages\django\db\models\query.py", line 1043, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 1054, in execute_sql
    cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py", line 337, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: column user_id is not unique

>>> from django.contrib.auth.models import User
>>> users = User.objects.all()
>>> users[1]
<User: dummy>
>>> response = c.post('http://127.0.0.1:8000/accounts/create_thing/', { 'name': 'dummy book', 'description': 'book for dummies', 'user_id': users[1].id })
Internal Server Error: /accounts/create_thing/
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
    response = get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\Working\Python\Django\Python2.7\Hello-Web-App\GitHub\Test\hellowebapp-code-master\collection\views.py", line 77, in create_thing
    thing.save()
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 796, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 824, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 908, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 947, in _do_insert
    using=using, raw=raw)
  File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Python27\lib\site-packages\django\db\models\query.py", line 1043, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 1054, in execute_sql
    cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py", line 337, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: column user_id is not unique
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "C:\Python27\lib\site-packages\django\test\client.py", line 541, in post
    secure=secure, **extra)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 343, in post
    secure=secure, **extra)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 409, in generic
    return self.request(**r)
  File "C:\Python27\lib\site-packages\django\test\client.py", line 494, in request
    six.reraise(*exc_info)
  File "C:\Python27\lib\site-packages\django\core\handlers\exception.py", line 39, in inner
    response = get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Python27\lib\site-packages\django\core\handlers\base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\Working\Python\Django\Python2.7\Hello-Web-App\GitHub\Test\hellowebapp-code-master\collection\views.py", line 77, in create_thing
    thing.save()
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 796, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 824, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 908, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 947, in _do_insert
    using=using, raw=raw)
  File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Python27\lib\site-packages\django\db\models\query.py", line 1043, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 1054, in execute_sql
    cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\Python27\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py", line 337, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: column user_id is not unique
>>>exit()

Thanks

Impavid
  • 435
  • 1
  • 6
  • 17

1 Answers1

5

This happens because you have OneToOneField, since that your every new Thing must be connected to User that wasn't picked before. So because you already had dummy_thing with dummy_user as User, you can't save new Thing instance with same dummy_user.

I believe your intention was that every Thing has a User, so you should use ForeignKey instead of OneToOneField.

But if i'm wrong, if you really need OneToOneField, then to test your POST request just create new user and login as new user, then thing.user = request.user will take dummy_user2 and there would be no conflicts with unique values.

class SampleTest(TestCase):
    def setUp(self):
        # Every test needs access to the request factory.
        self.factory = RequestFactory()
        self.dummy_user = User.objects.create_user(username='dummy', password='nothings')
        self.dummy_thing = Thing.objects.create(name="Dummy Book",
                                          description="Book For Dummies.",
                                          slug="dummy-book",
                                          user=self.dummy_user)
        self.dummy_user2 = User.objects.create_user(username='dummy2', password='nothing')

    def test_form_post(self):
        dummy_thing = Thing.objects.get(name="Dummy Book")
        self.client.login(username=dummy_thing2.user.username, password='nothing')

        # Test POST invalid data
        response = self.client.post('/accounts/create_thing/', { })
        self.assertFormError(response, 'form', 'name', 'This field is required.')
        self.assertFormError(response, 'form', 'description', 'This field is required.')
        self.assertTemplateUsed(response, 'things/create_thing.html')
        self.assertEqual(response.status_code, 200)

        # Test POST valid data? 
        response = self.client.post('/accounts/create_thing/', { 'name': 'new name', 'description': 'new description', })
        self.assertEqual(response.status_code, 200)
vishes_shell
  • 22,409
  • 6
  • 71
  • 81