Django : Dynamically create a database - python

I Would like to implement a web page in Django which allow a user to dynamically create a Data Base.
The Django model stored will always be the same. (a generic user)
Scenario :
The user fills up a form with fields like user.firstname, user.lastname ..
Then after the submit, django creates a brand new DB on the DBMS.
The model is then stored in this new DB.
Django save/store this DB setting for further use.
I find out Here that it's possible to set up multiple DB's in Django but that implies that they already have been created (Which is obviously not my case).
To create my DB I can think of executing an custom SQL query directly on the DBMS like that
from django.db import connection
def createNewDB(self,id):
with connection.cursort() as cursor:
queryStr = "\"CREATE DATABASE " + id + "\""
cursor.execute(queryStr)
But then I have no clues about :
How to save the new DB settings in Django DB (see below).
How to migrate and save the model user in the DB
Migrate :
from django.core.management import call_command
call_command("migrate", interactive=False)
Save model : user.save(using='db_id')
I find this post talking about how to add a connection dynamically with :
from django.db import connections
connections.databases['new-alias'] = { ... }
conn = connections['new-alias']
But again in, this case the sqlite DB exist before, so I'm not sure if it is what I need.
So is it possible to create a DB link to a model and then add it to django's database setting ?
Or should I review all my data structure ? (like one DB but multiple user model table)
I am using django 2.0.5 and postgreSQL 9.6 but I can change if the solution is not compatible (sqlite for example).

Related

Access Django DB objects without shell?

I have a request - can you help me access and manage django DB objects without using shell ?
I have created my models, but now (for example) i want to make a login system. I store users and passes(again, only an example), and i want to get the info from the DB, but i dont want to use shell.
What can i do in this case, im quite new to Django ?!
Best Regards
Why not use django-admin?
Maybe this is what you want:https://docs.djangoproject.com/en/3.0/ref/contrib/admin/
In views.py you can import
from .models import modelname
data = modelname.objects.all() - using this you can get all the data from the Database
Eg:-
for d in data:
print (d.email)
Will give all emails in the database
You can also use
t = modelname.objects.get(email='name#lk.com')
By this you can get the data of the person who's email is name#lk.com
Django already has database support where you can register your models and access them with a graphical interface.
See the documentation: django-admin-site
First you need to create a super user account, if you don't have one, create it with the terminal in the project directory, use this row:
python manage.py createsuperuser
For your model to appear on the admin site you need to register it
# models.py
class MyModel(models.Model)
field1 = models.CharField()
field2 = models.TextField()
# ...
# admin.py
from django.contrib import admin
from .models import MyModel
admin.site.register(MyModel)
So it's the basic way to register your model, if you want to personalize you need to check the documentation ModelAdmin.fieldsets
with this done, just access the admin site at the link http://localhost:8000/admin/ and log in with the super user account and you will see the model registered.

Database based forms in Flask

I am new to Flask and bit confused about the database modeling for it. Please have my apologies if by any mean this isn't a question eligible for post.
I need to create a multi choice model field in Flask and I need to be able to access it from backend admin panel to set values for it. It does shows options in docs with WTF forms to create multiple choice field. I am confused that how to create forms attached to Database. Can someone clear it up for me because I am a Django user and in Django Forms and ModelForms have different approach so trying to understand what would it be in Flask. How to render Database based forms in Flask? How would I create a multi choice field with database created for it. Please help.
What you are looking for is SQLAlchemy built-in ORM to build forms from models or integrated to database. There are other options to overcome limitations of Flask ORM when needed. Following is the example that would give you some clarity.
from flask import Flask, render_template, redirect, flash
from flask.wtf import Form
from flask.ext.sqlalchemy import SQLAlchemy
from wtf.ext.sqlalchemy.orm import model_form
app=Flask(__app__)
app.config['SECRET_KEY'] = 'secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/employees.sqlite'
app.config['SQLALCHEMY_ECHO'] = True
# Here you initiate the ext
db=SQLAlchemy(app)
#Let's define a model
class Employee(db.Model)
__tablename__ = 'employee'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False
birthday = db.Column(db.Date, nullable=False
def __repr__(self):
return 'employee %s' %self.name
# Now go to your shell inside your env not in gloabal shell outside your env and run this command.
# From your .py file where you've created all above configration first make an import to db from shell
from file.py import db
#Then create a database with following command in shell
db.create.all()
#Your auto generated database based form below
EmployeeForm() = model_form(Employee, base_class=Form, field_args{'name':{'class':'employee'}})
#Let's create a view with model_form or database based form in your case.
#app.route('/', methods=['GET', 'POST'])
def index()
#request.POST does same in Django or any other Python based web framework like Bottle, Tornado etc
form = EmployeeForm()
try:
if form_validate_on_submit():
employee=Employee() #load the model values
form.populate_obj(Employee) #populates the form with respective values
db.session.add(employee) #gathers the session based data to be added in DB
db.session.commit() #Adds data to DB
flash('New Employee added to database successfully.') #Display a message to end user at front end.
retrun redirect('/') # redirects upon success to your homepage.
except Exception e:
# logs the errors
db.session.rollback()
flash('There was a problem registering new employee. Please contact the site administrator at site#site.com')
employee_list = Employe.query.all() #equailent to django style "item.objects.all() to show list of all existing items.
return render_template('index.html', form=form, employee_list=employee_list)
In last line above you did three things. You got your form variable or context variable like you do in Django as "form" so your end user can enter data.
Then you have your model data that is saved in db as "employee_list=employee_list" that will show all the list to end users. "flash" is just like Django
messaging framework.
Now for multiple choices its model has same as djagno choice arguement for key value like below:
With my experience I would suggest you to install "peewee" a simple ORM for Python connected Databases.
choices = (('key', 'value')('key', 'value'))
employee_type = db.Model(db.String(90), choices=('key1', 'key2)
Hope this helps.

create_or_get with data from user input

Trying to implement a user registration form on a website I can't make user input to be added as a new user to the database. I'm using Flask with Peewee, and have:
nUser ={
'email': request.form['e_mail'],
'uname': request.form['username'],
'pword': request.form['password'],
'time': strftime('%Y-%m-%d %H:%M:%S')
}
nUser = User.create_or_get()
where nUser is temporary dict for new user. I should mention, that with the official peewee docs I tried nUser, created = User.create_or_get(nUser) what returned an error of too many arguments.
A code about User class is below (stored in separate .py, but there is from models import * up there):
class User(Model):
email=TextField()
uname=TextField(unique=True)
pword=TextField()
time=TextField()
class Meta:
database = db
Although it looks like it "works" from a webuser side, no record is added to the database. Previously I did it with User.select().where(User.uname...... and it worked, but now I would like to switch to create_or_get() method since it would shorten my code and looks more efficient. Logging in for old users works, so the connection and access to the DB is fine. I would appreciate any hints.
The official documentation that you link to show that create_or_get takes keyword arguments only. To pass a dict, you need to use the ** syntax:
User.create_or_get(**nuser)

Django+Mongodb file upload returns default primary key error

I am trying to write a simple file upload application with django + mongodb. I have set my SITE_ID properly (I am writing to the db).
Using the admin page, I can upload a file (and the file appears in the dir structure), but when I click on the filename:
It gives me this error:
DatabaseError at /admin/myapp/fileUpload/534855062da57ae6ecc4399f/myapp/files/1_2.jpg/
AutoField (default primary key) values must be strings representing an ObjectId on MongoDB (got u'534855062d...' instead).
This is the code I'm using:
models.py
class fileUpload(models.Model):
some_file_location = models.FileField(upload_to='myapp/files/')
admin.py
admin.site.register(fileUpload)
DB Entry:
db.myapp_fileupload.find()
{ "_id" : ObjectId("53484e4e2da57ad214df5072"), "some_file_location" : "myapp/files/1.jpg" }
This problem is related to the incompatibility of mongo and django. I have run into many problems with this, and at this point, a new solution (db or framework) is the best way to go.

Getting missing column error whenever a model is saved

I'm having trouble creating a model in django. I wrote a model like this:
from django.db import models
class FooModel(models.Model):
name = models.CharField(max_length = 255)
I run
manage.py syncdb
But when I'm in the shell, I can't save an instance. Every time I call it, it tells me it's missing a column
manage.py shell
>>from app.models import FooModel
>>foo = FooModel()
>>foo.name = 'foo'
>>foo.save()
DatabaseError: column "name" of relation "ecommerce_foomodel" does not exist
LINE 1: INSERT INTO "ecommerce_foomodel" ("name") VALUES (E'123123as...
We're using postgres.
The database table was created before you added the corresponding fields.
So, you can recreate all of the tables of that app (in case you don't have any useful data) using:
python manage.py reset ecommerce
Or, you should migrate the database to the latest version using South.

Categories

Resources