Django: Having arbitrary file access models - python

Seems like a really simple issue I am having, but for whatever reason I cannot get an arbitrary file i create within a Django app to access my models/compile.
analytics/
analytics/
settings.py
etc...
mapper/
models.py
views.py
filetoDothings.py
I would like "fileToDoThings.py" do things with my models, but when i put even a few simple lines of code in filetodothings, and try to import the models i get the following error: "Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure()"
A lot of searching has led me to find answers similar to this:
sys.path.append("path/toproject")
os.environ["DJANGO_SETTINGS_MODULE"] = "myApp.settings"
from django.contrib.auth.models import ModelName
This worked, but only when i moved the arbitrary file to the outermost "analytics" directory. Even though I got this to work, it never quite seemed to make sense to me/seemed like a lot of work to get a file to access models in the same directory.
So what I am trying to do now is the following, in filetoDothings.py:
from models import Addresses
usaMapPoints = Addresses.objects.filter(countryCode='US').order_by("-frequency")[:25]
print(usaMapPoints)
For "messing around" purposes, I want to call "python filetodothings.py" and have it print the results in the console. But ultimately Im just trying ot get my head around how to create a file that can be automated later on.
I have seen the code for another Django app and someone was able to do exactly this.
Am I missing something really simple?

I would like "fileToDoThings.py" do things with my models
To do arbitrary operations from the command line, write a new Django management command.
You write your ‘lorem_ipsum.py’ module within a particular app, placing it a fooapp/management/commands/lorem_ipsum.py. Write it to define a command as per the documentation above.
Then you can invoke that as a management command: python3 -m manage lorem_ipsum.
Am I missing something really simple?
Simple, yes; obvious, no.
Django is a framework, not a library. The difference has been characterised by saying that with a library, you write code that calls the library; with a framework, you write code that gets called by the framework.
In other words, the way to get things done in a framework is to find the places where your code fits, and write it to fit those places.

looks like you need create command
https://docs.djangoproject.com/en/1.10/howto/custom-management-commands/

Related

Django - How to port scripts to django

Before I ask my question I need to give some context:
I wrote a simple python script that read linux's syslog file and search for certain strings. I have other similar scripts like these (scripts that do file system stuff, scripts that interact with other servers and so on). Most of these scripts write simple write stuff to stdout.
I would like to port these scripts to a web-server so I could simple browser to https://server/syslog and get the same output that I would get by running the script on the command line interface.
According with my research Django seems to be a great choice. I followed some Django tutorials and I was capable of developing some basic django web apps.
My question is: Since django does not have a "controller" where should I place the scripts code? My best bet in the view, but according with djangos documentation it does not make sence.
Extracted from django doc: In our interpretation of MVC, the “view” describes the data that gets presented to the user. It’s not necessarily how the data looks, but which data is presented. The view describes which data you see, not how you see it. It’s a subtle distinction.
The description of MVC is not so important. The typical use of django is for database backed web applications. And this describes a design pattern or paradigm for that. It's completely possible to use django in other ways as well.
If you want to build a django app that is a web interface for your existing scripts, you might not even need the django ORM at all. In any case, you can put as much or as little logic in your view as you want. Your use case might just not fit neatly into the MVC or MVT paradigm. Django views are just python functions (or classes, but Django class based views are more tightly coupled with the ORM).
I would recommend:
leaving your scripts largely as they are, but wrap the parts you want to reuse as
functions. You can keep them functional as standalone scripts with an
if __name__=='__main__':
block to call the functions.
Import the functions to views.py - it doesn't matter where they are as long as your server will always be able to find them. I put mine right in the app directory.
Call the function(s) in your view(s), and return the text to a HttpResponse object which you return from the view. (I think this is more direct than creating a template and a context and calling render, but its not what I usually do so there may be some issues?)
Thats bit old code - but you will get enough idea to start - check https://github.com/alex2/django_logtail (Django_LogTail)

where to put non-model classes in django

I'm now using django 1.6
As I know, if I want to use some model classes (using ORM) I should put them under folder myapp/models.py.
So what if I want to write some non-model classes (not using ORM), i.e. class Util, and only contains some globally used methods, maybe date formatting or something else.
So, where should these code locate? Is there a generally used way to this case?
You can really put them anywhere you like, but I follow the pattern Django itself uses (in admin, cache, etc.) and put such things in a utils.py file. I have one (if necessary) in each app folder, as well as one for the whole project.

Best practices for getting the most testing coverage with Django/Python?

My tests are seriously lacking and I don't have a whole lot of faith in them. What are some of the best practices for getting the most testing coverage I can using Django/Python? I've been taking a look at Freshen and Lettuce, which look pretty promising, but I can't use them for everything, can I? I'm looking for advice on how to structure my workflow/project with testing so that I can feel confident when deploying new code in a production environment.
Stop coding.
Write the tests for the things your application is supposed to do.
First, use the built-in Django testing. Write model tests as TestCase classes inside your models.py.
Do that now. Before reading any further. Add django.test.TestCase classes right now that create, modify and retrieve model objects. Be sure you have a test method for each property, attribute, or extra method you defined.
I'll wait until you've finished that.
Model tests complete? Good.
Now create a tests.py file in each application. Every single one. All empty.
In each tests.py file create django.test.TestCase classes for each Form.
Do it now. Create good and bad forms. Create forms with each individual field validation problem.
Don't create all possible permutations of bad data. Just one test case for each individual validation rule.
Do that now. Before reading any further. Add django.test.TestCase classes to tests.py for each Form.
I'll wait until you've finished that.
Now, you have to test each view function. They also go in the tests.py file. Each view function has at least two test cases, perhaps more, depending on the various decorators you're using.
If a view function requires a login, you have two cases: logged in and not logged in.
If a view function requires a permission, you have at least three cases: not logged in, logged in as the wrong user, logged in as the right user.
For now, you just need to be sure that the view function did something and returns the correct HTML template with any piece of correct data. Don't go crazy. You just want to be sure all view functions actually return an expected page. Nothing more.
Do that now. Before reading any further. Add django.test.TestCase classes to tests.py for each view function.
I'll wait until you've finished that.
Those are the tests you should write first before writing any application code.
This will give you a testing baseline that confirms that your application will minimall sort-of run.
One you have that finished, you can start to consider unit tests that reflect the real purpose and value behind your application.
Additionally this series of articles so far has some good advice on testing django apps:
http://toastdriven.com/blog/2011/apr/10/guide-to-testing-in-django/
My only criticism of the answer would be to not store everything in the tests.py file, but do as the article suggest. Create a tests directory and turn it in to a module by adding an __init__.py file and importing all your test cases there. eg from myapp.tests.views import *. But definitely sound advice. Gotta walk before you can run… tests! See what I did there?
I'm assuming that you are done with Testing Django Applications. With the right set of helper tools you should be fine with the default unit testing using Django test framework.
To get you started with measuring coverage you might want to look into coverage standalone to figure out what you have tested.
Once installed, you can do something like this:
$ coverage run manage.py test *yourapp*
It will create .coverage file for you. You can format the data from this file with
$ coverage report
to get a full list on testing coverage (including code from other python libraries).
You can easily coverage report --omit path modules that start with particular paths. Additionally you would be able to see the lines that were not executed during the test run with -m option.
Also, I think there is a django_coverage Django application that integrates coverage into testing for Django project. It makes nice HTML coverage reports for you.
Now there are other tools like twill, etc. to address specific needs (like javascript testing).
Also, if you want to go through the detailed baby steps of setting up vanilla testing under Django, you may want to read "Django 1.1 Testing and Debugging" (lookup on Amazon).

Django: "projects" vs "apps"

I have a fairly complex "product" I'm getting ready to build using Django. I'm going to avoid using the terms "project" and "application" in this context, because I'm not clear on their specific meaning in Django.
Projects can have many apps. Apps can be shared among many projects. Fine.
I'm not reinventing the blog or forum - I don't see any portion of my product being reusable in any context. Intuitively, I would call this one "application." Do I then do all my work in a single "app" folder?
If so... in terms of Django's project.app namespace, my inclination is to use myproduct.myproduct, but of course this isn't allowed (but the application I'm building is my project, and my project is an application!). I'm therefore lead to believe that perhaps I'm supposed to approach Django by building one app per "significant" model, but I don't know where to draw the boundaries in my schema to separate it into apps - I have a lot of models with relatively complex relationships.
I'm hoping there's a common solution to this...
Once you graduate from using startproject and startapp, there's nothing to stop you from combining a "project" and "app" in the same Python package. A project is really nothing more than a settings module, and an app is really nothing more than a models module—everything else is optional.
For small sites, it's entirely reasonable to have something like:
site/
models.py
settings.py
tests.py
urls.py
views.py
Try to answer question: "What does my
application do?". If you cannot answer
in a single sentence, then maybe you can
split it into several apps with cleaner
logic.
I read this thought somewhere soon after I've started to work with django and I find that I ask this question of myself quite often and it helps me.
Your apps don't have to be reusable, they can depend on each other, but they should do one thing.
What is to stop you using myproduct.myproduct? What you need to achieve that roughly consists of doing this:
django-admin.py startproject myproduct
cd myproduct
mkdir myproduct
touch myproduct/__init__.py
touch myproduct/models.py
touch myproduct/views.py
and so on. Would it help if I said views.py doesn't have to be called views.py? Provided you can name, on the python path, a function (usually package.package.views.function_name) it will get handled. Simple as that. All this "project"/"app" stuff is just python packages.
Now, how are you supposed to do it? Or rather, how might I do it? Well, if you create a significant piece of reusable functionality, like say a markup editor, that's when you create a "top level app" which might contain widgets.py, fields.py, context_processors.py etc - all things you might want to import.
Similarly, if you can create something like a blog in a format that is pretty generic across installs, you can wrap it up in an app, with its own template, static content folder etc, and configure an instance of a django project to use that app's content.
There are no hard and fast rules saying you must do this, but it is one of the goals of the framework. The fact that everything, templates included, allows you to include from some common base means your blog should fit snugly into any other setup, simply by looking after its own part.
However, to address your actual concern, yes, nothing says you can't work with the top level project folder. That's what apps do and you can do it if you really want to. I tend not to, however, for several reasons:
Django's default setup doesn't do it.
Often, I want to create a main app, so I create one, usually called website. However, at a later date I might want to develop original functionality just for this site. With a view to making it removable (whether or not I ever do) I tend to then create a separate directory. This also means I can drop said functionality just by unlinking that package from the config and removing the folder, rather than a complex delete the right urls from a global urls.py folder.
Very often, even when I want to make something independent, it needs somewhere to live whilst I look after it / make it independent. Basically the above case, but for stuff I do intend to make generic.
My top level folder often contains a few other things, including but not limited to wsgi scripts, sql scripts etc.
django's management extensions rely on subdirectories. So it makes sense to name packages appropriately.
In short, the reason there is a convention is the same as any other convention - it helps when it comes to others working with your project. If I see fields.py I immediately expect code in it to subclass django's field, whereas if I see inputtypes.py I might not be so clear on what that means without looking at it.
I've found the following blog posts very useful about django applications and projects:
http://www.b-list.org/weblog/2006/sep/10/django-tips-laying-out-application/
http://web.archive.org/web/20080302205555/www.pointy-stick.com/blog/2007/11/09/django-tip-developing-without-projects/
In principle, you have a lot of freedom with django for organizing the source code of your product.
If so... in terms of Django's project.app namespace, my inclination is to usemyproduct.myproduct, but of course this isn't allowed
There is nothing like not allowed. Its your project, no one is restricting you. It is advisable to keep a reasonable name.
I don't see any portion of my product being reusable in any context. Intuitively, I would call this one "application." Do I then do all my work in a single "app" folder?
In a general django project there are many apps (contrib apps) which are used really in every project.
Let us say that your project does only one task and has only a single app (I name it main as thethe project revolves around it and is hardly pluggable). This project too still uses some other apps generally.
Now if you say that your project is using just the one app (INSTALLED_APPS='myproduct') so what is use of project defining the project as project.app, I think you should consider some points:
There are many other things that the code other than the app in a project handles (base static files, base templates, settings....i.e. provides the base).
In the general project.app approach django automatically defines sql schema from models.
Your project would be much easier to be built with the conventional approach.
You may define some different names for urls, views and other files as you wish, but I don't see the need.
You might need to add some applications in future which would be real easy with the conventional django projects which otherwise it may become equally or more difficult and tedious to do.
As far as most of the work being done in the app is concerned, I think that is the case with most of django projects.
Here Django creators points out that difference themselves.
I think that thinking about Apps as they have to be reusable in other projects is good. Also a good way of thinking about Apps in Django provide modern web applications.
Imagine that you are creating big dynamic web app basing on JavaScript.
You can create then in django App named e.g "FrontEnd" <-- in thins app you will display content.
Then you create some backend Apps. E.g App named "Comments" that will store user comments. And "Comments" App will not display anything itself. It will be just API for AJAX requests of your dynamic JS website.
In this way you can always reuse your "Comments" app. You can make it open source without opening source of whole project. And you keep clean logic of your project.

How to externally populate a Django model?

What is the best idea to fill up data into a Django model from an external source?
E.g. I have a model Run, and runs data in an XML file, which changes weekly.
Should I create a view and call that view URL from a curl cronjob (with the advantage that that data can be read anytime, not only when the cronjob runs), or create a python script and install that script as a cron (with DJANGO _SETTINGS _MODULE variable setup before executing the script)?
There is excellent way to do some maintenance-like jobs in project environment- write a custom manage.py command. It takes all environment configuration and other stuff allows you to concentrate on concrete task.
And of course call it directly by cron.
You don't need to create a view, you should just trigger a python script with the appropriate Django environment settings configured. Then call your models directly the way you would if you were using a view, process your data, add it to your model, then .save() the model to the database.
I've used cron to update my DB using both a script and a view. From cron's point of view it doesn't really matter which one you choose. As you've noted, though, it's hard to beat the simplicity of firing up a browser and hitting a URL if you ever want to update at a non-scheduled interval.
If you go the view route, it might be worth considering a view that accepts the XML file itself via an HTTP POST. If that makes sense for your data (you don't give much information about that XML file), it would still work from cron, but could also accept an upload from a browser -- potentially letting the person who produces the XML file update the DB by themselves. That's a big win if you're not the one making the XML file, which is usually the case in my experience.
"create a python script and install that script as a cron (with DJANGO _SETTINGS _MODULE variable setup before executing the script)?"
First, be sure to declare your Forms in a separate module (e.g. forms.py)
Then, you can write batch loaders that look like this. (We have a LOT of these.)
from myapp.forms import MyObjectLoadForm
from myapp.models import MyObject
import xml.etree.ElementTree as ET
def xmlToDict( element ):
return dict(
field1= element.findtext('tag1'),
field2= element.findtext('tag2'),
)
def loadRow( aDict ):
f= MyObjectLoadForm( aDict )
if f.is_valid():
f.save()
def parseAndLoad( someFile ):
doc= ET.parse( someFile ).getroot()
for tag in doc.getiterator( "someTag" )
loadRow( xmlToDict(tag) )
Note that there is very little unique processing here -- it just uses the same Form and Model as your view functions.
We put these batch scripts in with our Django application, since it depends on the application's models.py and forms.py.
The only "interesting" part is transforming your XML row into a dictionary so that it works seamlessly with Django's forms. Other than that, this command-line program uses all the same Django components as your view.
You'll probably want to add options parsing and logging to make a complete command-line app out of this. You'll also notice that much of the logic is generic -- only the xmlToDict function is truly unique. We call these "Builders" and have a class hierarchy so that our Builders are all polymorphic mappings from our source documents to Python dictionaries.

Categories

Resources