how to access django models with script outside of the project - django

I have two projects. The new one bases on Django and the old one based on PHP. Both are alive. I want to synchronize all info between these projects. I have a python script which parse all info from the PHP project but I can't load it to the Django project.
The only way I found to solve the problem is to connect to sqllite DB of the django project from my python script. But I feel that this solution is not the best&
Is there a way to write smth like this in my python script:
from .models import MyModel
for (f1, f2, f3) in parse_results:
result = MyModel.objects.create(field1=f1, field2=f2, field3=f3)
For now when i try to import MyModel i see
ModuleNotFoundError: No module named '__main__.models'; '__main__' is not a package

You can write your script code in a Django custom command, in this way you have access to your Django models.

Related

How to add site models to Cookiecutter Django project

I have a Cookiecutter Django project in which I'd like to add a "SiteSettings" model to control constants. My first instinct was to run manage.py startapp site. However I received the following message:
CommandError: 'site' conflicts with the name of an existing Python module and cannot be used as an app name. Please try another name.
Upon closer inspection, it appears that Cookiecutter already created a sites module within contrib, but with no models.py file. So I decided to make a models.py with the SiteSettings model in this directory.
However when I run makemigrations it says: No changes detected in app 'sites'
How can I add my desired model to this module and get migrations working for this module?
You will run into countless problems if you follow this path. Just use another name and do manage.py startapp newname.

How to call a function before a django app start?

In my django project i have to check if a database/table exist before starting application, i don't know how is better insert the code for check.
I try to add in views.py into login function a try except block but i was try to find an elegant and more effective solution.
Thanks in advance
To check before the app starts then you can use the AppConfig.ready() function. This gets called before the application starts, but after your project has started. If you want to check before the project starts then you will have to hook into the method you use to start your project, eg within wsgi.py or even manage.py
AppConfig.ready() docs Note that the docs specifically say
avoid interacting with the database in your ready() implementation.
But your use case may justify doing this.
The ready function is called when you run the commands from manage.py eg
manage.py shell / manage.py migrate / etc
It won't get called when your site is visited of course. If you want to run a DB check in response to a visitor action then that code should go into your view
You put the ready() function in your apps.py:
from django.apps import AppConfig
from django.db import connection
class MyAppConfig(AppConfig):
name = 'MyApp'
def ready(self):
print("i am the ready function and the database test code goes here")
# put your test code here, eg you could read all the tables from sqlite
with connection.cursor() as cursor:
cursor.execute("SELECT name FROM sqlite_master;")
rows=cursor.fetchall()
print (rows)
You can write your custom django admin commands and run it by using python manage.py your_command right before calling python manage.py runserver. There are detailed examples at the official documentation.
One of the advantages of using commands is that testing commands are fairly easy. Django has a package for calling commands django.core.management.call_command which enables funtionally test your command.

Google App Engine Interactive Console: ImportError: No module named models

I have a django project running on my local server under the google app engine python SDK 1.9.7.
I want to run a query in the interactive console. I have a model called Flatpage
I put the seemingly appropriate handler in the app.yaml file, namely:
url: /admin/.*
script: google.appengine.ext.admin.application
login: admin
From the docs i understood that when the local development server is running the interactive console on the admin server would be running in the same environment as the a project. Yet:
the interactive console does not recognize any of my model classes and when i try to import models I get an error: ImportError: No module named models
I have tried adding the local path to the models.py file to the directory as well as various names like app.models, appname.models and projectname.models to no avail.
However. when I copy and paste the models file into the interactive console it works.
Would someone explain how to import the models file into the interactive console,
and, secondly, why the interactive console, which seemingly should already have the models defined when the server starts, needs to have the models defined again, anyway, thanks!
I'm not sure why you're adding that handler to use the console locally, but what I do is use the Development Console (available since last year), which by default runs on port 8000, from there (localhost:8000/console most likely) you can import modules from your project.
For example if you have models.py in the same directory as app.yaml, you should be able to do:
import models
entity = models.Flatpage()
with no problem.

How to execute a python program by a button click on html page generated by django

I created a Django project to launch a htmlpage which has a button with name run test. I would like to run a python script file hello.py(located outside the django project) when the button is clicked. I am quite new to this scripting.
Can anyone help me with this question as soon as possible? Your help would be appreciated.
My django project consists of following files:
TestProject(project folder)
myapp(folder)
int.py
admin.py
models.py
tests.py
urls.py
views.py
Templates(folder)
index.html
Testproject(folder)
int.py
urls.py
settings.py
views.py
wsgi.py
admin.py
manage.py
The python script file-helllo.py is located C:/hello.py
There are two basic approaches you could take to do this:
(1) Run the script as a subprocess (i.e. execute a separate program outside of your django application) - this is documented in the Python docs on subprocesses. Below is a brief example, you will need to go through the docs to understand exactly how you want to call your script (i.e. to handle return codes, output to stdout and stderr, etc)
import subprocess
subprocess.call(["python", "C:/hello.py"])
(2) If there is a specific function in this script that you could call, then you could add the directory containing the python script to sys.path, and then import the script and call the relevant function. This is detailed in this stack overflow question, and would be arguably the cleaner approach (As a sidenote, would advise moving hello.py to a more suitable location, the root of your C: drive probably isn't the right place to store scripts).
import sys
sys.path.append("C:/")
from hello import function_to_call
function_to_call()
If you are struggling to put together the web page that allows you to display the button and react to the button press by calling the script, it would be advisable to work through the excellent Django tutorial writing your first Django application.

ImportError when using Haystack 2.0.0 with Django 1.5 and Gunicorn WSGI

I use django-haystack 2.0.0 to index my site, and it has been working great until I upgraded to Django 1.5 and started using the WSGI interface. If I just use the django_gunicorn command it works great, but the Django documentation "highly recommends" I use the gunicorn command.
When I start my site with the gunicorn command, Haystack throws the following error on any page load:
ImportError: cannot import name signals
I have no problems importing signals from the Django or Python shells. I use virtualenv and install all packages locally inside that environment. My wsgi.py file looks just like the default one in the django admin, except that I add the local path to the python path as such:
path = os.sep.join(os.path.abspath(__file__).split(os.sep)[:-2])
if path not in sys.path:
sys.path.append(path)`
Any help you could provide would be very appreciated, thank you!
I don't use gunicorn, but I had the same problem when I used the HAYSTACK_SIGNAL_PROCESSOR setting to point to a custom class that I wrote. That class imported one of my models, which eventually propagated up the import chain, to import my settings module, thus causing a circular import.
When using a setting such as HAYSTACK_SIGNAL_PROCESSOR that points to a class, make sure that class standsalone, and doesn't import either directly or indirectly the Django settings file.