Say we create a Model like this:
def model_factory(*args, **kwargs):
attrs = {}
attrs['Meta'] = type('Meta', (object,), {
'verbose_name': 'My Dynamic model',
'db_table': 'dynamic_model_table'
})
# Ex. add an arbitrary fields
attrs['username'] = models.CharField(
max_length = 128,
db_column = 'username'
)
attrs['email'] = models.CharField(
max_length = 128,
db_column = 'email'
)
return type('DynamicModel', (models.Model,), attrs)
How do I specify the column order in the database? I.e the CREATE statement must be
CREATE TABLE "dynamic_model_table" (
"username" varchar(128) NOT NULL,
"email" varchar(128) NOT NULL
)
Using the code example however, the column order will be random.
Related
I am trying to create a expense claim app, i have created a form where a user can claim a expense ,when the admin Logs in the following webpage in the picture appears and the webpages iterates all the claims that have claim_status == Null, i want the admin to be able to accept or reject the claim from the dropdown and it to update the value for that object in the database and webpage to refresh and that claim showing no more
I have given a initial value of Null for the ExpenseClaim model and when user fills the expense claim form he cannot see the claim_status field
please see my models
class ExpenseClaim(models.Model):
reference_number = models.AutoField(primary_key=True)
employee_name = models.CharField(max_length=150)
employee_ID = models.CharField(max_length=150)
claim_initiating_date = models.DateTimeField(auto_now=True)
invoice_date = models.DateField()
invoice_location = models.CharField(max_length=150)
biller_name = models.CharField(max_length=150)
invoice_category = models.CharField(max_length=150)
price = models.DecimalField(decimal_places=2, max_digits=10, null=False , default=0.00)
GST = models.DecimalField(decimal_places=2 ,max_digits=10, null=False , default=0.00)
CGST = models.DecimalField(decimal_places=2 ,max_digits=10, null=False , default=0.00)
IGST = models.DecimalField(decimal_places=2, max_digits=10, null=False , default=0.00)
Total_amount = models.DecimalField(decimal_places=2 ,max_digits=10, null=False , default=0.00)
mode_of_payement = models.CharField(max_length=20)
Payment_reference = models.BooleanField()
invoice = models.FileField()
claim_status = models.CharField(default=None , max_length=10)
payment_status = models.CharField(default= None , max_length=10)
Following is my models field i tried to create a new form but that just creates a new object in the database i want to update the existing one
invoice_category_choices =[
('food',"food"),
('travel',"travel"),
('accodmodation',"accomodation"),
('fuel',"fuel"),
# ('others',"others"),
]
claim_status_choices = [
('accepted' , 'accepted'),
('rejected' , 'rejected')
]
payment_status_choices =[
('paid' , 'paid'),
('notpaid' , 'notpaid')
]
class ExpenseClaimForm(forms.ModelForm):
class Meta:
model = ExpenseClaim
exclude = [
"employee_name",
"employee_ID",
"claim_status",
"payment_status"
]
widgets = {
'invoice_date': forms.DateInput(format=('%m/%d/%Y'), attrs={'class':'form-control', 'placeholder':'Select a date', 'type':'date'}),
'invoice_category':forms.Select(choices= invoice_category_choices),
'claim_status':forms.Select(choices= claim_status_choices)
}
class ClaimStatusForm(forms.ModelForm):
class Meta:
model = ExpenseClaim
fields = [
"claim_status",
]
widgets = {
'claim_status':forms.Select(choices= claim_status_choices)
}
forms.py
class ClaimStatusForm(forms.ModelForm):
class Meta:
model = ExpenseClaim
fields = [
"claim_status",
]
widgets = {
'claim_status':forms.Select(choices= claim_status_choices)
}
views .py
def admin_update_view(request , reference_number):
post = get_object_or_404(ExpenseClaim , reference_number=reference_number)
form = ClaimStatusForm(instance=post)
if request.method == 'POST':
post = get_object_or_404(ExpenseClaim , reference_number=reference_number)
form = ClaimStatusForm(request.POST)
if form.is_valid():
claim_status = form.cleaned_data.get('claim_status')
post.claim_status = claim_status
post.save()
return redirect('/admin/')
context = { "form":form , "initialize_context" : initialize_context(request)}
return render(request , 'graphauth/adminupdate.html' , context)
urls.py
path('adminupdate/<int:reference_number>', views.admin_update_view , name='adminupdate'),
admin.html
update
I have a Users table and a Tasks table. The Tasks table has an "author" column and an "assignee" column, both of which are foreign keys to the unique ID in Users.
As you might expect, this produced an error: "Could not determine join condition between parent/child tables on relationship Users.created_tasks - there are multiple foreign key paths linking the tables."
What's another way to record both the "author" and "assignee" if I wanted to have both columns in the table?
class Tasks(db.Model):
// ...
author = db.Column(db.Integer, db.ForeignKey('users.id'))
assignee = db.Column(db.Integer, db.ForeignKey('users.id'))
class Users(db.Model, UserMixin):
// ...
created_tasks = db.relationship('Tasks', backref = 'ctasks_user')
assigned_tasks = db.relationship('Tasks', backref = 'atasks_user')
You can specify the primaryjoin attribute of each relationship to differentiate the two:
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
connection_uri = (
"mssql+pyodbc://#localhost:49242/myDb?driver=ODBC+Driver+17+for+SQL+Server"
)
engine = sa.create_engine(connection_uri)
with engine.begin() as conn:
conn.execute(sa.text("DROP TABLE IF EXISTS task_t"))
conn.execute(sa.text("DROP TABLE IF EXISTS user_t"))
Base = declarative_base()
class Task(Base):
__tablename__ = "task_t"
id = sa.Column(sa.Integer, primary_key=True)
description = sa.Column(sa.String(50))
author = sa.Column(sa.Integer, sa.ForeignKey("user_t.id"))
assignee = sa.Column(sa.Integer, sa.ForeignKey("user_t.id"))
def __repr__(self):
return f"<Task(id={self.id}, description='{self.description}')>"
class User(Base):
__tablename__ = "user_t"
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String(50))
created_tasks = relationship(
Task,
primaryjoin="User.id == Task.author",
backref="user_created_tasks",
)
assigned_tasks = relationship(
Task,
primaryjoin="User.id == Task.assignee",
backref="user_assigned_tasks",
)
def __repr__(self):
return f"<User(id={self.id}, name='{self.name}')>"
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
homer = User(name="Homer")
bart = User(name="Bart")
lisa = User(name="Lisa")
session.add_all([homer, bart, lisa])
session.commit()
mow_the_lawn = Task(
description="Mow the lawn", author=homer.id, assignee=bart.id
)
wash_the_car = Task(
description="Wash the car", author=homer.id, assignee=lisa.id
)
session.add_all([mow_the_lawn, wash_the_car])
session.commit()
with engine.begin() as conn:
result = conn.execute(
sa.text("SELECT * FROM user_t ORDER BY id")
).fetchall()
print(result)
# [(1, 'Homer'), (2, 'Bart'), (3, 'Lisa')]
result = conn.execute(
sa.text("SELECT * FROM task_t ORDER BY id")
).fetchall()
print(result)
# [(1, 'Mow the lawn', 1, 2), (2, 'Wash the car', 1, 3)]
print(homer.created_tasks)
# [ <Task(id=1, description='Mow the lawn')>, <Task(id=2, description='Wash the car')>]
print(bart.assigned_tasks)
# [ <Task(id=1, description='Mow the lawn')>]
I have a Django site, and am using windows auth for it. When I try to logon as a new user it gives the error Cannot insert the value NULL into column 'id', table 'table.auth_user'; column does not allow nulls. INSERT fails. One other thing to mention is that that I have a separate db for my Auth (but the AuthDB is the default one).
models.py
class AuthUser(models.Model):
password = models.CharField(max_length=128)
last_login = models.DateTimeField(blank=True, null=True)
is_superuser = models.BooleanField()
username = models.CharField(unique=True, max_length=150)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=150)
email = models.CharField(max_length=254)
is_staff = models.BooleanField()
is_active = models.BooleanField()
date_joined = models.DateTimeField()
class Meta:
managed = False
db_table = 'auth_user'
def __str__(self):
return self.username
In settings.py
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'AuthDB',
'HOST': 'MyHost',
'USER': '',
'PASSWORD': '',
'OPTIONS': {
'driver':"ODBC Driver 13 for SQL Server",
},
'CONN_MAX_AGE': 60,
},
I am not sure why django is trying to insert the value of NULL into the the auto added primary key id. Maybe I am missing something? Does anyone have any idea why?
Thanks for the help!
When am trying to add new Unique_id (uuid) field in the existing django models , It returns the intgerity error.
models.py:
class Directory(models.Model):
unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
name = models.CharField(max_length=120)
path = models.CharField(max_length=240)
Views.py:
def get_dir_dict(request, dir):
dir_info['pk'] = query.pk
dir_info['unique_id'] = query.unique_id
dir_info['name'] = query.name
dir_info['path'] = query.path
error:
File "/home/sitharth/zeal/lib64/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: could not create unique index "zkloud_directory_unique_id_key"
DETAIL: Key (unique_id)=(734e8926-386b-47a9-9ac0-d617f45f7113) is duplicated.
I want to create a form that hides a field. This works:
form_class = modelform_factory( Model, widgets = { 'field1' : forms.HiddenInput() }, exclude = () )
form = form_class() # field1 is hidden
Why doesn't it work when I create the form_class and then set the widgets through its meta class?
form_class = modelform_factory( Model, exclude=() )
form_class._meta.widgets = { 'field1' : forms.HiddenInput() }
form = form_class() # field1 is not hidden in form