I am going through online tutorial for a basic Django web page and a single app.
The first and only thing I have done so far is to create the project and a single app with the sqllite database.
I have added the app to the settings.py file correctly.
Within the app models.py I have defined a single model.
The makemigrations command has successfully created the database for the model.
After creating the model class, I attempted to write the following test script to test the constructor of the model. This script lives in the app directory at the same level as the models.py.
from django.test import TestCase
from models import Foodie # the model
import os
# Create your tests here.
class TestModel(unittest.TestCase):
def test_foodie(self):
tc = Foodie()
if __name__ == '__main__':
unittest.main()
I get the error:
builtins.IndexError: list index out of range
File "C:\WebDev\DinnerServer\Rolls\tests.py", line 2, in <module>
from models import Foodie
File "C:\WebDev\DinnerServer\Rolls\models.py", line 7, in <module>
class Foodie(models.Model):
File "C:\Python33\Lib\site-packages\Django-1.7.1-py3.3.egg\django\db\models\base.py", line 116, in >__new__
kwargs = {"app_label": package_components[app_label_index]}
(The app where the model resides is titled Rolls)
How or why is this failing and how do I set the app_label for the unit test to work?
Basic error, the import statement is wrong.
Should be... from Rolls.models
you need to add def __str__(self): to your Foodie model in models.py.
class Foodie(models.Model):
#some fields
def __str__(self):
# you access to model fiels here
return self.label
Also see the doc may help you.
Related
I want to create a new user's login and random/same password using CSV file using the ImportExport module Django. I've tried many examples but for no use. Can you please suggest anything? I've even tried to make password field in the import csv file. Let me know any tutorial/link that you can share to achieve this.
If you're looking to populate the database with dummy data, there is a module called faker in python.
Here is a small code snippet showing how you can use faker:
import os
# Configure settings for project
# Need to run this before calling models from application!
os.environ.setdefault('DJANGO_SETTINGS_MODULE','(YOUR DJANGO PROJECT).settings')
import django
# Import settings
django.setup()
import random
from (YOUR DJANGO APP).models import User
from faker import Faker
fakegen = Faker()
def populate(N=5):
for entry in range(N):
# Create Fake Data for entry
fake_name = fakegen.name().split()
fake_first_name = fake_name[0]
fake_last_name = fake_name[1]
fake_email = fakegen.email()
# Create new User Entry
user = User.objects.get_or_create(first_name=fake_first_name,
last_name=fake_last_name,
email=fake_email)[0]
if __name__ == '__main__':
print("Populating the databases...")
populate(20)
print('Populating Complete')
django-import-export contains several hooks which you can use to manipulate data prior to insertion in the db. This seems like the ideal way to generate a random password for each user.
You can combine this with Django's make_random_password() function. It doesn't seem like a good idea to have passwords in the import spreadsheet, but maybe you need to do that for some reason.
You will need to create your own Resource subclass, and override the before_save_instance(), for example:
class UserResource(resources.ModelResource):
def before_save_instance(self, instance, using_transactions, dry_run):
pw = User.objects.make_random_password()
instance.set_password(pw)
class Meta:
model = User
fields = ('id', 'username', 'password')
import_id_fields = ['id']
I have functions in my admin Class that I'd like to perform on a regular basis (every 10 minutes). I am trying to use the "custom django-admin commands" solution ( https://docs.djangoproject.com/en/3.1/howto/custom-management-commands/#howto-custom-management-commands ) and will use a cron job to run it.
I do have the custom command working with test code, however I am running into a few issues:
I'm not sure how to initialize the class (I get errors such as "missing 1 required positional argument"). If I skip instantiation I can call the functions explicitly, but then I run into these next two problems.
I'm used to calling internal Admin class functions using "self.functionname()". But 'self' doesn't work when called from my custom management command.
Many of my admin functions use the standard 'request' argument; however I don't have a 'request' from my custom management command.
These code snippets are paraphrased from the originals.
polls/management/commands/performTasks.py
from django.core.management.base import BaseCommand, CommandError
from polls.models import Question
from polls.admin import QuestionAdmin
class Command(BaseCommand):
help = 'Starts the process.'
def handle(self, *args, **options):
QuestionAdmin.tasks(self, 'YES')
# The following 2 lines I simply use to prove a successful query:
myqueryset = Question.objects.filter(author="Tolkien")
print(myqueryset)
admin.py
from django.contrib import admin
from .models import Question
from django.urls import path
from django.http import HttpResponse, HttpResponseRedirect
#admin.register(Question)
class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text']
def tasks(self, arg1):
# This does print "YES" so I know the custom management command works.
print(arg1)
# again, the following 2 lines I simply use to prove a successful query:
myqueryset = Question.objects.filter(author="Tolkien")
print(myqueryset)
# This next line fails from the Custom management command with:
# AttributeError: 'Command' object has no attribute 'stepOne'
self.stepOne(self, request, myqueryset)
def stepOne(self, request, queryset):
result = self.stepTwo(request, queryset)
def stepTwo(self, request, queryset):
''' The actual function performs a logic test and returns True or False. '''
return True
models.py
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
author = models.CharField(max_length=200, unique=True)
So 3 questions... heavily related:
What's the correct way to initialize my admin Class?
How do I propagate 'self' through my admin Classes functions?
How could I handle the missing 'request' arguments?
Also any comments about the feasibility of using the Custom Management command would be welcome. My goal is to use a complex set of function (that already work from the Admin class) on a regular (every 10 minutes) basis.
In the docs for Django's System check framework it says:
Checks should be registered in a file that’s loaded when your application is loaded; for example, in the AppConfig.ready() method.
None of the examples on that page, or around the AppConfig.ready() method, show how to do this. Given a checking method like:
from django.core.checks import register, Tags
#register(Tags.compatibility)
def my_check(app_configs, **kwargs):
# ... perform compatibility checks and collect errors
return errors
How would you do this in/from the AppConfig.ready() method? Is one called from the other? Which file should the above method go in? Do you add #register(...) to the ready() method?
From reading the examples on this page about the Apps Registry and System Checks Framework, it seems there are (at least) two ways to add your own System Checks. To adapt that page's examples (assuming you're creating an app called myapp):
1) Create a myapp/checks.py file like this:
from django.apps import apps as camelot_apps
from django.core.checks import register, Warning
from django.core.checks import Tags as DjangoTags
class Tags(DjangoTags):
"""Do this if none of the existing tags work for you:
https://docs.djangoproject.com/en/1.8/ref/checks/#builtin-tags
"""
my_new_tag = 'my_new_tag'
#register(Tags.my_new_tag)
def check_taggit_is_installed(app_configs=None, **kwargs):
"Check that django-taggit is installed when usying myapp."
errors = []
try:
from taggit import models
except ImportError:
errors.append(
Warning(
"The django-taggit app is required to use myapp.",
hint=("Install django-taggit"),
# A unique ID so it's easier to find this warning:
id='myapp.W001',
)
)
return errors
And then in myapp/__init__.py (create it if it doesn't exist):
from . import checks
Running this should run that check above:
$ ./manage.py check myapp
2) Or, as I thought in my initial question, you can register that check in your AppConfig. So, keep the above code in myapp/check.py, but remove the #register(Tags.my_new_tag) line.
Then create myapp/apps.py containing this:
from django.core.checks import register
from .checks import Tags, check_taggit_is_installed
class MyappConfig(AppConfig):
name = 'myapp'
def ready(self):
super(MyappConfig, self).ready()
register(Tags.my_new_tag)(check_taggit_is_installed)
And alter myapps/__init__.py so it contains this:
from . import checks
default_app_config = 'myapp.apps.MyappConfig'
The first example seems simpler, with no need for a custom AppConfig.
Django recommends:
Checks should be registered in a file that’s loaded when your application is loaded; for example, in the AppConfig.ready() method.
Therefore, place the checks code in a checks.py file. Then simply in apps.py, as with signals:
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'MyApp'
verbose_name = "My App"
def ready(self):
# import myapp.signals
import myapp.checks
My guess is that you can just place this code in ready() method. For example of usage you can take a look at django.contrib.auth (or other contrib app). This app has check in checks.py file, that imported in apps.py and registered in ready() method: checks.py, apps.py.
I am trying to upload documets in appengine-django.
Docs getting uploaded successfully with pure django code [ using python manage.py runsever ].
But when i am trying to run django with appengine project it gives me error ,
[Errno 30] Read-only file system: u'/home/nishant/workspace1/problemdemo/uploaded_files/1372313114_43_nishant26062013.zip'
This error caused because Developers have read-only access to the filesystem on App Engine.
Is there is another way to upload docs to google cloud sql ?
Here is my code ,
models.py
from django.db import models
import time
# Create your models here.
def get_upload_file_name(instance,filename):
return "uploaded_files/%s_%s" % (str(time.time()).replace('.','_'),filename)
class Candidate(models.Model):
title=models.CharField(max_length=20)
resume=models.FileField(upload_to=get_upload_file_name)
def __unicode__(self):
return self.title
forms.py
from django import forms
from actualproblem.models import Candidate
class TestForm(forms.ModelForm):
class Meta:
model=Candidate
fields=('title','resume',)
views.py
# Create your views here.
from django.shortcuts import render
from actualproblem.forms import TestForm
def sampletest(request):
if request.method=='POST':
form = TestForm(request.POST,request.FILES)
if form.is_valid():
form.save()
else:
form=TestForm()
return render(request,'profile.html',{'form':form})
How can i upload documetns to google cloud sql ?
You may solve the conundrum by using Uploadcare, it can help in situations when you have little or no control over host filesystem (GAE, heroku, shared hosting or whatnot). Uploaded files will be stored in Uploadcare and you will store file UUIDs or URLs in your DB.
There is Django package: pyuploadcare
disclosure: I am one of Uploadcare developers and am posting this not to shamelessly promote the service but because it was built to solve cases like this one.
I have some external services. My Django app is built on top of my external service APIs. In order to talk to my external service, I have to pass in an auth cookies, which I can get by reading User (that cookie != django cookies).
Using test tools like webtests, requests, I have trouble writing my tests.
class MyTestCase(WebTest):
def test_my_view(self):
#client = Client()
#response = client.get(reverse('create')).form
form = self.app.get(reverse('create'), user='dummy').form
print form.fields.values()
form['name'] = 'omghell0'
print form
response = form.submit()
I need to submit a form, which creates, say, a user on my external service. But to do that, I normally would pass in request.user (in order to authenticate my privilege to external service). But I don't have request.user.
What options do I have for this kind of stuff?
Thanks...
Suppose this is my tests.py
import unittest
from django.test.client import Client
from django.core.urlresolvers import reverse
from django_webtest import WebTest
from django.contrib.auth.models import User
class SimpleTest(unittest.TestCase):
def setUp(self):
self.usr = User.objects.get(username='dummy')
print self.usr
.......
I get
Traceback (most recent call last):
File "/var/lib/graphyte-webclient/webclient/apps/codebundles/tests.py", line 10, in setUp
self.usr = User.objects.get(username='dummy')
File "/var/lib/graphyte-webclient/graphyte-webenv/lib/python2.6/site-packages/django/db/models/manager.py", line 132, in get
return self.get_query_set().get(*args, **kwargs)
File "/var/lib/graphyte-webclient/graphyte-webenv/lib/python2.6/site-packages/django/db/models/query.py", line 341, in get
% self.model._meta.object_name)
DoesNotExist: User matching query does not exist
But if I test the User.objects in views, I am okay.
You need to use the setUp() method to create test users for testing - testing never uses live data, but creates a temporary test database to run your unit tests. Read this for more information: https://docs.djangoproject.com/en/dev/topics/testing/?from=olddocs#writing-unit-tests
EDIT:
Here's an example:
from django.utils import unittest
from django.contrib.auth.models import User
from myapp.models import ThisModel, ThatModel
class ModelTest(unittest.TestCase):
def setUp(self):
# Create some users
self.user_1 = User.objects.create_user('Chevy Chase', 'chevy#chase.com', 'chevyspassword')
self.user_2 = User.objects.create_user('Jim Carrey', 'jim#carrey.com', 'jimspassword')
self.user_3 = User.objects.create_user('Dennis Leary', 'dennis#leary.com', 'denisspassword')
Also note that, if you are going to use more than one method to test different functionality, you should use the tearDown method to destroy objects before reinstantiating them for the next test. This is something that took me a while to finally figure out, so I'll save you the trouble.
def tearDown(self):
# Clean up after each test
self.user_1.delete()
self.user_2.delete()
self.user_3.delete()
Django recommends using either unit tests or doc tests, as described here. You can put these tests into tests.py in each apps directory, and they will run when the command `python manage.py test" is used.
Django provides very helpful classes and functions for unit testing, as described here. In particular, the class django.test.Client is very convenient, and lets you control things like users.
https://docs.djangoproject.com/en/1.4/topics/testing/#module-django.test.client
Use the django test client to simulate requests. If you need to test the behavior of the returned result then use Selenium.