Django Tests User Object - python

I'm testing a django app from this tutorial: http://tutorial.djangogirls.org/en/django_admin/README.html
I've created a test:
from django.test import TestCase
from django.utils import timezone
from .models import Post
from django.contrib.auth.models import User
# Create your tests here.
class PostTest(TestCase):
def test_create_post(self):
# Create the post
post = Post()
# Set the attributes
post.author = User
post.title = 'My first post'
post.text = 'This is my first blog post'
post.published_date = timezone.now()
post.created_date = timezone.now()
# Save it
post.save()
# Check we can find it
all_posts = Post.objects.all()
self.assertEquals(len(all_posts), 1)
only_post = all_posts[0]
self.assertEquals(only_post, post)
# Check attributes
self.assertEquals(only_post.author, User)
self.assertEquals(only_post.title, 'My first post')
self.assertEquals(only_post.text, 'This is my first blog post')
self.assertEquals(only_post.published_date.day, post.published_date.day)
self.assertEquals(only_post.published_date.month, post.published_date.month)
self.assertEquals(only_post.published_date.year, post.published_date.year)
self.assertEquals(only_post.published_date.hour, post.published_date.hour)
self.assertEquals(only_post.published_date.minute, post.published_date.minute)
self.assertEquals(only_post.published_date.second, post.published_date.second)
self.assertEquals(only_post.created_date.day, post.created_date.day)
self.assertEquals(only_post.created_date.month, post.created_date.month)
self.assertEquals(only_post.created_date.year, post.created_date.year)
self.assertEquals(only_post.created_date.hour, post.created_date.hour)
self.assertEquals(only_post.created_date.minute, post.created_date.minute)
self.assertEquals(only_post.created_date.second, post.created_date.second)
When I run python manage.py test I get this error:
Creating test database for alias 'default'...
ERROR: test_create_post (blog.tests.PostTest)
Traceback (most recent call last):
File "C:\Users\shenk\Documents\Programming\django_projects\djangogirls\blog\tests.py" , line 13, in test_create_post
post.author = User
File "c:\Users\shenk\Documents\Programming\django_projects\djangogirls\myvenv\lib\site-packages\django\db\models\fields\related.py", line 627, in __set__
self.field.rel.to._meta.object_name,
ValueError: Cannot assign "<class 'django.contrib.auth.models.User'>": "Post.author" must be a "User" instance.
----------------------------------------------------------------------
Ran 1 test in 0.001s
How can I create an object of User instance to test the Post? In my model it's defined as author = models.ForeignKey('auth.User')

This line looks bogus:
# Set the attributes
post.author = User
post.author is expecting for you to assign an instance of the User class to it, not the User class itself. Try something like:
u = User(...)
u.save()
post.author = u

Related

Django test fails with "No User matches the given query."

I wrote Django app and now I'm trying to cover it with automated tests. For testing get_queryset function within my ListView I created a test user and his post, but my test fails with "No User matches the given query". When I execute py manage.py runserver everything is fine, no exceptions are raised and the page's displayed properly. I'm new to Django testing so I absolutely have no idea what's going on. Could you help me please?
This is my view from view.py
class UserPostListView(ListView):
"""Displaying a page with a certain user's posts"""
model = Post
template_name = 'blog/user_posts.html'
context_object_name = 'posts'
paginate_by = 5
def get_queryset(self):
"""Dynamic filtering to get posts by a chosen user"""
queryset = super().get_queryset()
user = get_object_or_404(User, username=self.kwargs.get('username'))
return queryset.filter(author=user).order_by('-date_posted')
Test for that view:
class TestUserPostListView(TestCase):
"""Test UserPostListView"""
def setUp(self):
"""Creating a test user and his post to see if the certain
user's page with posts is displayed properly"""
self.factory = RequestFactory()
self.user = User.objects.create_user(
username='test_user',
email='testuser#example.com',
password='fhhewo87539275'
)
self.post = Post.objects.create(
title='test_post',
content='blabla',
author=self.user
)
def test_get_queryset(self):
"""Testing get_queryset function"""
url = reverse('user-posts', kwargs={'username': self.user.username})
request = self.factory.get(url)
view = UserPostListView()
view.setup(request)
queryset = view.get_queryset()
self.assertIn(self.post, queryset)
Traceback:
Traceback (most recent call last):
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\shortcuts.py", line 76, in get_object_or_404
return queryset.get(*args, **kwargs)
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\db\models\query.py", line 435, in get
raise self.model.DoesNotExist(django.contrib.auth.models.User.DoesNotExist: User matching query does not exist.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\473491\Documents\django\web_blog\web_blog\apps\blog\test\test_views.py", line 67, in test_get_queryset
queryset = view.get_queryset()
File "C:\Users\473491\Documents\django\web_blog\web_blog\apps\blog\views.py", line 45, in get_queryset
user = get_object_or_404(User, username=self.kwargs.get('username'))
File "C:\Users\473491\Documents\django\web_blog\env\lib\site-packages\django\shortcuts.py", line 78, in get_object_or_404
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
django.http.response.Http404: No User matches the given query.
I have found out where the problem was. My UserPostListView is called by the url containing url-variable.
My urlpattern corresponding to the view:
path('users/<str:username>', UserPostListView.as_view(), name='user-posts')
I also use username from the url to filter out posts created by the user with that username by calling get_queryset function in UserPostListView.
I read the docs attentively and found:
When the view is called during the request/response cycle, the setup() method assigns the HttpRequest to the view’s request attribute, and any positional and/or keyword arguments captured from the URL pattern to the args and kwargs attributes, respectively.
It means that instead of view.setup(request) I had to write view.setup(request, username=self.user.username)
When I fixed it the test started running properly and didn't fail.

GraphQL queries in Django returning None

I am trying to use graphQL queries in django. Basically I have two apps, my 'api' app which contains everything I need to make the queries and another one called 'frontend' from which I call the api to use these queries.
I can use the GraphQL view to type queries in it and it works perfectly, but whenever I try to make the query, I get this: "OrderedDict([('users', None)])"
Result of my query in the GraphQl view
The code:
In 'api' my schema.py:
import graphene
import graphql_jwt
from graphene import relay, ObjectType, AbstractType, List, String, Field,InputObjectType
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from datetime import date, datetime
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model
....
class Query(graphene.ObjectType):
me = graphene.Field(UserType)
users = graphene.List(UserType)
profile = relay.Node.Field(ProfileNode)
all_profiles = DjangoFilterConnectionField(ProfileNode)
def resolve_users(self, info):
### Returns all users ###
user = info.context.user
if user.is_anonymous:
raise Exception('Not logged!')
if not user.is_superuser:
raise Exception('premission denied')
return User.objects.all()
def resolve_me(self, info):
### Returns logged user ###
user = info.context.user
if user.is_anonymous:
raise Exception('Not logged!')
return user
def resolve_all_profiles(self, info, **kwargs):
### Returns all profiles ###
return Profile.objects.all()
.....
def execute(my_query):
schema = graphene.Schema(query=Query)
return schema.execute(my_query)
And the views.py that calls the app 'api' in my app frontend:
from django.shortcuts import render
import graphene
from api import schema
from django.contrib.auth import authenticate
def accueil(request):
if request.user.is_authenticated:
check = "I am logged"
else:
check = "I am not logged"
result = schema.execute("""query {
users {
id
username
}
}""")
return render(request, 'frontend/accueil.html', {'result' : result.data, 'check' : check})
The template :
<h1>OTC</h1>
<p> the users are : {{result}}</p>
<br/>
<p>{{check}}</p>
login
logout
and finally:
The web page result
and the error in the console:
An error occurred while resolving field Query.users
Traceback (most recent call last):
File "/home/victor/myenv/lib/python3.5/site-packages/graphql/execution/executor.py", line 311, in resolve_or_error
return executor.execute(resolve_fn, source, info, **args)
File "/home/victor/myenv/lib/python3.5/site-packages/graphql/execution/executors/sync.py", line 7, in execute
return fn(*args, **kwargs)
File "/home/victor/poc2/poc2/api/schema.py", line 67, in resolve_users
user = info.context.user
AttributeError: 'NoneType' object has no attribute 'user'
Traceback (most recent call last):
File "/home/victor/myenv/lib/python3.5/site-packages/graphql/execution/executor.py", line 330, in complete_value_catching_error
exe_context, return_type, field_asts, info, result)
File "/home/victor/myenv/lib/python3.5/site-packages/graphql/execution/executor.py", line 383, in complete_value
raise GraphQLLocatedError(field_asts, original_error=result)
graphql.error.located_error.GraphQLLocatedError: 'NoneType' object has no attribute 'user'
Unless you're writing a test client, you probably should not be calling schema.execute from inside a Django view. But assuming that you have your reasons for doing this, your specific problem is that you're not passing the user when you invoke schema.execute in accueil view.
Have a look at the execute documentation and you'll see that you'll need to supply an optional argument for the context. Your code is not supplying a context, hence the info.context is None, as per your exception. Unfortunately, the example
result = schema.execute('{ name }', context_value={'name': 'Syrus'})
is not Django-specific. But I think what works in a Django functional view is:
result = schema.execute(query, context_value=request)

Django notification giving error for other model

Following code is working for comment section.
from django.db import models
from django.contrib.sites.models import Site
from django.db.models import signals
from notification import models as notification
def new_comment(sender, instance, created, **kwargs):
# remove this if-block if you want notifications for comment edit too
if not created:
return None
context = {
'comment': instance,
'site': Site.objects.get_current(),
}
recipients = []
# add all users who commented the same object to recipients
for comment in instance.__class__.objects.for_model(instance.content_object):
if comment.user not in recipients and comment.user != instance.user:
recipients.append(comment.user)
# if the commented object is a user then notify him as well
if isinstance(instance.content_object, models.get_model('auth', 'User')):
# if he his the one who posts the comment then don't add him to recipients
if instance.content_object != instance.user and instance.content_object not in recipients:
recipients.append(instance.content_object)
notification.send(recipients, 'friends_invite', context)
signals.post_save.connect(new_comment, sender=models.get_model('comments', 'Comment'))
But when we implement the same code for other custome model comment then it giving error at the time of entering the record in model.
from django.db import models
from django.contrib.sites.models import Site
from django.db.models import signals
from notification import models as notification
def create_notice_types(app, created_models, verbosity, **kwargs):
notification.create_notice_type("friends_invite", _("Invitation Received"), _("you have received an invitation"))
notification.create_notice_type("friends_accept", _("Acceptance Received"), _("an invitation you sent has been accepted"))
signals.post_syncdb.connect(create_notice_types, sender=notification)
def new_comment(sender, instance, created, **kwargs):
# remove this if-block if you want notifications for comment edit too
if not created:
return None
context = {
'gufeed_feedcomment': instance,
}
recipients = []
# add all users who commented the same object to recipients
for comment in instance.__class__.objects.for_model(instance.content_object):
if comment.user not in recipients and comment.user != instance.user:
recipients.append(comment.user)
# if the commented object is a user then notify him as well
if isinstance(instance.content_object, models.get_model('auth', 'User')):
# if he his the one who posts the comment then don't add him to recipients
if instance.content_object != instance.user and instance.content_object not in recipients:
recipients.append(instance.content_object)
notification.send(recipients, 'friends_invite', context)
signals.post_save.connect(new_comment, sender=models.get_model('gufeed_feedcomment', 'FeedHottPoint'))
Note: we are taking friends_invite notification type this is already created
ERROR:
AttributeError at /gufeed/comment/add/
'Manager' object has no attribute 'for_model'

Getting User Object for forms.py

I have an app called profiles which just leverages the django-registration-redux module. I am trying to create a form that allows the user to edit it, with the information they already have in it, but it isn't showing up. I can get it to show up without the information, but not the profile information that already exists.
urls.py
from django.conf.urls import url
from profiles import views
urlpatterns = [
url(r'^(?P<username>[-\w]+)/$', views.single, name='profile_single'),
url(r'^(?P<username>[-\w]+)/edit/$', views.edit, name="profile_edit"),
]
views.py
def edit(request, username):
instance = Profile.objects.get(user=username)
# It would be good to have an in depth understanding of what the actual request module does
if request.user == instance.user:
form = ProductForm(request.POST or None, instance = instance)
if form.is_valid():
profile = form.save(commit=False)
profile.user = request.user
profile.slug = slugify(form.cleaned_data['title'])
profile.save()
return HttpResponseRedirect('/user/%s'%(user.username))
return render_to_response("profiles/edit.html", locals(), context_instance=RequestContext(request))
The error that I am recieving is:
Exception Value: invalid literal for int() with base 10: 'admin'
You need to check username field of User model.
To do that, replace the following line:
instance = Profile.objects.get(user=username)
with:
instance = Profile.objects.get(user__username=username)

how to retrieve the user name from the database?

please help fix the error
I added to the site and access authorization system to the user profile . Each user has the ability to change the login. for this he must in the following form to enter login and click submit:
from django import forms
from userprofile.models import UserProfile
from django.contrib.auth.models import User
from django.conf import settings
import os
class UserProfileForm (forms.ModelForm):
class Meta:
model = UserProfile
fields = ('family', 'name', 'nation', 'status', 'login', 'nation_show')
def clean_family (self):
family = self.cleaned_data ['family']
letters_quantity = len (family)
if letters_quantity < 4 :
raise forms.ValidationError (" little beech in the name! " )
return family
def clean_login (self):
login = self.cleaned_data ['login']. strip ()
if login! ='':
login_form_db = User.objects.filter (username = 'qwe')
if login_form_db:
login_form_db = login_form_db.username
if login == login_form_db:
raise forms.ValidationError (" this username is busy " )
else:
User.username = login
User.save (self)
return login
but in the end I get the following message error :
AttributeError at / userprofile /
'QuerySet' object has no attribute 'username'
Request Method: POST
Request URL: http://127.0.0.1:8000/userprofile/
Django Version: 1.6.2
Exception Type: AttributeError
Exception Value:
'QuerySet' object has no attribute 'username'
Exception Location: c: \ Python33 \ django_projects \ mutants \ userprofile \ forms.py in clean_login, line 26
filter() returns a queryset. Since you need to get the User object by username, use get() instead:
login_form_db = User.objects.get(username='qwe')

Categories

Resources