Multi-Table Django Join - mysql

Relatively new to Django. I'm building a light CRM in Django. The MYSQL database I built uses associative entities to help deal with many-to-many relationships.
I'm trying to use the associative entity "contactdeal" to connect "deals" with "contacts".
See models and views below.
Models:
class Account1(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, blank=True, null=True)
address = models.CharField(max_length=255, blank=True, null=True)
city = models.CharField(max_length=255, blank=True, null=True)
state = models.CharField(max_length=255, blank=True, null=True)
country = models.CharField(max_length=255, blank=True, null=True)
description = models.CharField(max_length=255, blank=True, null=True)
phone = models.CharField(max_length=255, blank=True, null=True)
email = models.CharField(max_length=255, blank=True, null=True)
biztype = models.CharField(max_length=255, blank=True, null=True)
notes = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'account'
class Contact1(models.Model):
contact_id = models.AutoField(primary_key=True)
first_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255, blank=True, null=True)
account_id = models.ForeignKey(Account1, models.DO_NOTHING, db_column='account_id', blank=False, null=False)
contact_notes = models.TextField(blank=True, null=True)
contact_email = models.CharField(max_length=255, blank=True, null=True)
contact_phone = models.CharField(max_length=255, blank=True, null=True)
contact_status = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'contact'
class Contactdeal(models.Model):
contactdeal_id = models.AutoField(primary_key=True)
contactdeal_deal_fk = models.ForeignKey('Deal', models.DO_NOTHING, db_column='contactdeal_deal_fk', blank=True, null=True)
contactdeal_contact_fk = models.ForeignKey(Contact1, models.DO_NOTHING, related_name='contactdeal_contact_fk', db_column='contactdeal_contact_fk', blank=True, null=True)
class Meta:
managed = False
db_table = 'contactdeal'
class Deal(models.Model):
deal_id = models.AutoField(primary_key=True)
deal_name = models.CharField(max_length=255, blank=True, null=True)
est_value = models.DecimalField(max_digits=13, decimal_places=2, blank=True, null=True)
deal_notes = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'deal'
View:
def deal(request):
deal = Contactdeal.objects.select_related('contactdeal_contact_fk', 'contactdeal_deal_fk')
template = loader.get_template('deal.html')
context = {
'deal' : deal,
}
return HttpResponse(template.render(context, request))
Template:
{% for x in deal %}
<tbody>
<tr class="table-active">
<td>{{x.contactdeal_deal_fk.deal_name}}</td>
<td>{{x.contactdeal_deal_fk.est_value}}</td>
<td>{{x.contactdeal_contact_fk.first_name}}</td>
<td>{{x.contactdeal_contact_fk.account_id}}</td>
<td>Update</td>
<td>Delete</td>
</tr>
</tbody>
{% endfor %}
for the most part, I've been successful using the select_related approach to join both contacts and deals using the associative entity contactdeal.
Where this falls short, however, is when I want to show the "account" each "contact" belongs to. I can show "account_id" which is the FK that links the "contact" table and "account" table, but I can't seem to come up with a way to add another join that will allow me to use the "account_id" FK in the contact table to pull the name associated with that "account_id" in the "account" table.

I think I figured it out. I am going to try to create a view in MYSQL that achieves the connection I am looking to establish and turn that into its own model, not managed using Django.

Related

init mysql database in Django got error: django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 3072 bytes')

I have used Django to develop a web app.
When I tried to init the mysql database using python manage.py migrate, I got the error:
_
Operations to perform:
Apply all migrations: admin, auth, bms, contenttypes, notifications, reversion, sessions
Running migrations:
Applying bms.0002_auto_20210610_1003...Traceback (most recent call last):
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\mysql\base.py", line 71, in execute
return self.cursor.execute(query, args)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\MySQLdb\cursors.py", line 206, in execute
res = self._query(query)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\MySQLdb\cursors.py", line 319, in _query
db.query(q)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\MySQLdb\connections.py", line 259, in query
_mysql.connection.query(self, query)
MySQLdb._exceptions.OperationalError: (1071, 'Specified key was too long; max key length is 3072 bytes')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\base.py", line 364, in execute
output = self.handle(*args, **options)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\management\commands\migrate.py", line 234, in handle
fake_initial=fake_initial,
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\executor.py", line 117, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\executor.py", line 147, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\executor.py", line 245, in apply_migration
state = migration.apply(state, schema_editor)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\migration.py", line 124, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\migrations\operations\models.py", line 530, in database_forwards
getattr(new_model._meta, self.option_name, set()),
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\base\schema.py", line 367, in alter_unique_together
self.execute(self._create_unique_sql(model, columns))
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\base\schema.py", line 137, in execute
cursor.execute(sql, params)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 99, in execute
return super().execute(sql, params)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\backends\mysql\base.py", line 71, in execute
return self.cursor.execute(query, args)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\MySQLdb\cursors.py", line 206, in execute
res = self._query(query)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\MySQLdb\cursors.py", line 319, in _query
db.query(q)
File "C:\Users\hcnguyen\AppData\Local\Programs\Python\Python37\lib\site-packages\MySQLdb\connections.py", line 259, in query
_mysql.connection.query(self, query)
django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 3072 bytes')
I have tried :
ALTER DATABASE databasename CHARACTER SET utf8;
CREATE DATABASE mydatabase CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
All failed in my case.
model.py:
class User(AbstractUser):
user_type = models.CharField(max_length=12, choices=USER_TYPE_CHOICES, null=True, blank=True)
auth_source = models.CharField(max_length=10, null=True, blank=True, default='local') # Local or LDAP
#is_external = models.BooleanField("Is Non-SUSS user", default=False) # for vendors (Publisher, Makono, Distributor/Vendor)
# avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)
executives = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='hop_executives', blank=True) # for executives report to HOP
def __str__(self):
return self.username
class TimeStampedModel(models.Model):
"""
An abstract base class model that provides self-updating
``created`` and ``modified`` fields.
"""
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
ordering = ['modified']
class BaseModel(TimeStampedModel):
creator = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Created by', blank=True, null=True,
related_name="%(app_label)s_%(class)s_created", on_delete=models.SET_NULL)
updater = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Updated by', blank=True, null=True,
related_name="%(app_label)s_%(class)s_updated", on_delete=models.SET_NULL)
def save(self, *args, **kwargs):
if self.pk is None and hasattr(local, 'user'):
self.creator = local.user
return super(BaseModel, self).save(*args, **kwargs)
class Meta:
abstract = True
class School(models.Model): # school or center
code = models.CharField(max_length=20, unique=True)
name = models.CharField(max_length=190)
cost_center = models.CharField(max_length=12) # UC1001, GF1004
def __str__(self):
return self.name
'''
class Discipline_code(models.Model): # school or center
code = models.CharField(max_length=20, unique=True)
Discipline = models.CharField(max_length=200)
Discipline_code = models.CharField(max_length=12) # UC1001, GF1004
# __str__ method is used to override default string returned by an object
def __str__(self):
return self.Discipline'''
class Discipline(TimeStampedModel):
#code = models.CharField(max_length=20, db_index=True)
name = models.CharField(max_length=190)
school = models.ForeignKey(School, on_delete=models.SET_NULL, blank=True, null=True)
hop1 = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='primary_hop', on_delete=models.SET_NULL, blank=True,
null=True) # Head of Program, as primary
hop2 = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='secondary_hop', on_delete=models.SET_NULL, blank=True,
null=True) # Head of Program, as backup?
executive = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='executive', on_delete=models.SET_NULL, blank=True,
null=True) # Head of Program, as backup?
executive2 = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='executive2', on_delete=models.SET_NULL, blank=True,
null=True) # Head of Program, as backup?
executive3 = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='executive3', on_delete=models.SET_NULL, blank=True,
null=True) # Head of Program, as backup?
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
class CourseInfo(TimeStampedModel): # school or center
code = models.CharField(max_length=20, db_index=True)
#code = models.CharField(max_length=20, db_index=True)
title = models.CharField(max_length=190)
school = models.ForeignKey(School, on_delete=models.SET_NULL, blank=True, null=True)
postgraduate = models.BooleanField(default=False) # indicate Postgraduate course
discipline = models.ForeignKey(Discipline, on_delete=models.SET_NULL, blank=True, null=True) # should not be null
discipline_code = models.CharField(max_length=20, blank=True, null=True)
last_semester_presented = models.CharField(max_length=20, blank=True, null=True)
pattern = models.CharField(max_length=120, choices=PRESENTATION_PATTERN, blank=True, null=True,
help_text="Presentation Pattern")
type = models.TextField(blank=True)
available = models.BooleanField(default=True) # mean Active or Retired
semesters = models.ManyToManyField('Semester', through="Course") # auto have semestercourse_set
# __str__ method is used to override default string returned by an object
def __str__(self):
#return "{} - {}".format(self.code, self.title)
return "{}".format(self.title)
class Meta:
#constraints = [models.UniqueConstraint(fields=['code', 'type'], condition=models.Q(available=True),
# name='unique_course_type')]
#unique_together = ('discipline_code', 'code', 'type', 'semesters')
ordering = ['code', ]
class Semester(models.Model): # the semester where the book is used
year = models.PositiveIntegerField()
month = models.CharField(max_length=20)
slug = models.SlugField(default='', editable=False, max_length=190)
courses = models.ManyToManyField(CourseInfo, through="Course")
class Meta:
unique_together = ('year', 'month')
ordering = ('-year', '-month',)
def save(self, *args, **kwargs):
value = "{}{}".format(self.month, self.year)
self.slug = slugify(value, allow_unicode=True)
super().save(*args, **kwargs)
# __str__ method is used to override default string returned by an object
def __str__(self):
return "{}{}".format(self.month, self.year)
class Course(models.Model): # CourseInfo Quota
courseInfo = models.ForeignKey(CourseInfo, on_delete=models.CASCADE)
semester = models.ForeignKey(Semester, on_delete=models.CASCADE)
term = models.IntegerField(default=1) # Optional, Term start: 1 or 2
quota = models.IntegerField(blank=True, null=True) # total student enrolment
titles = models.ManyToManyField('Title', through="Material") # performance issue, it will load all books, for the DRF only
class Meta:
# must add unique_together for course, course_type and semester
ordering = ('semester',)
def __str__(self):
return "{}_{}".format(self.courseInfo.code, self.semester)
# relation containing Publisher of books
class Publisher(models.Model):
name = models.TextField(blank=True, help_text="Publisher name")
contact = models.CharField(max_length=50, blank=True, null=True)
def __str__(self):
return self.name
class Meta:
ordering = ['name', ]
CURRENCY_SGD = 'SGD'
CURRENCY_USD = 'USD'
CURRENCY_GBP = 'GBP'
CURRENCY_CHOICES = ((CURRENCY_SGD, 'SGD'), (CURRENCY_USD, 'USD'), (CURRENCY_GBP, 'GBP'))
LANG_CHOICES = (('en', 'English'), ('ch', "Chinese"), ('ta', "Tamil"), ('ma', "Malay"), ('ot', "Other"))
# must run createinitialrevisions whenever register a new model
# e.g: python3 manage.py createinitialrevisions bms.Book --comment="Initial revision."
# #reversion.register()
class Title(TimeStampedModel):
type = models.CharField("Category", max_length=20, default='Textbook',
choices=(('Textbook', 'Textbook'), ('iSG', 'iStudy Guide'), ('Course Guide', 'Course Guide'),
('Practicum Handbook', 'Practicum Handbook'), ('Software', 'Software'), ('Reading', 'Reading'),
('Companion Site', 'Companion Site'))) # iSG, Book, etc
title = models.CharField(max_length=100, db_index=True)
author = models.CharField(max_length=100, blank=True, null=True)
description = models.TextField(max_length=190, help_text="Enter a brief description of the book", blank=True,
null=True)
isbn = models.CharField('ISBN', max_length=25,
help_text='13 Characters ISBN number',
blank=True, null=True)
isbn_pbk = models.CharField('ISBN Paperback', max_length=25,
help_text='This is alternative format to be adopted if the main is out of stock',
blank=True, null=True)
isbn_10 = models.CharField('ISBN (10)', max_length=10, blank=True, null=True)
e_isbn = models.CharField('e_isbn', max_length=10, blank=True, null=True)
e_isbn_2 = models.CharField('e_isbn_2', max_length=10, blank=True, null=True)
publisher = models.ForeignKey('Publisher', on_delete=models.SET_NULL, blank=True, null=True)
pub_date = models.CharField('date published', max_length=10, blank=True, null=True)
edition = models.CharField(max_length=10, blank=True, null=True)
language = models.CharField(max_length=5, choices=LANG_CHOICES, default='en')
page_count = models.IntegerField(blank=True, null=True)
info_link = models.CharField(max_length=190, blank=True, null=True)
retail_price = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
retail_price_cur = models.CharField(max_length=4, choices=CURRENCY_CHOICES,
default=CURRENCY_SGD)
e_price = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
e_price_cur = models.CharField(max_length=4, choices=CURRENCY_CHOICES,
default=CURRENCY_SGD) # etextbook price
suss_price = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True) # price for suss
suss_price_cur = models.CharField(max_length=4, choices=CURRENCY_CHOICES,
default=CURRENCY_SGD) # always SGD
cover = models.ImageField(blank=True, null=True, upload_to='book_image')
thumbnail = models.ImageField(blank=True, null=True, upload_to='book_image')
is_etextbook = models.BooleanField(default=False) # etextbook
vbid = models.CharField(max_length=50, blank=True, null=True) # Vitalsource book ID
print_available = models.BooleanField(default=False) # for ibookstore to show/hide Printing function
bridge_available = models.BooleanField(default=False) # for ibookstore to indicate available on VS Bridge
_version = models.IntegerField(default=1) # to control version
slug = models.SlugField(default='', editable=False, max_length=190)
Format_issued = models.CharField(max_length=100, blank=True, null=True)
Distribution_platform = models.CharField(max_length=100, blank=True, null=True)
Shared_Text_Title_Remark = models.CharField(max_length=100, blank=True, null=True)
STOCK = models.CharField(max_length=100, blank=True, null=True)
Total_StockAndWrap = models.CharField(max_length=100, blank=True, null=True)
Order_Qty_1st = models.CharField(max_length=100, blank=True, null=True)
Order_Qty_2nd = models.CharField(max_length=100, blank=True, null=True)
Order_Qty_3rd = models.CharField(max_length=100, blank=True, null=True)
Order_Qty_4th = models.CharField(max_length=100, blank=True, null=True)
Total_StocktakeAndQty_Purchase = models.CharField(max_length=100, blank=True, null=True)
Buffer = models.CharField(max_length=100, blank=True, null=True)
Discard_Status = models.CharField(max_length=100, blank=True, null=True)
Qty_to_Discard = models.CharField(max_length=100, blank=True, null=True)
Reason_for_discarding_stock = models.CharField(max_length=100, blank=True, null=True)
Print_Unit_Price = models.CharField(max_length=100, blank=True, null=True)
Total_Cost_Wastage = models.CharField(max_length=100, blank=True, null=True)
PO_Number = models.CharField(max_length=100, blank=True, null=True)
Invoice_Number = models.CharField(max_length=100, blank=True, null=True)
Supplier = models.CharField(max_length=100, blank=True, null=True)
Supplier_Contact = models.CharField(max_length=100, blank=True, null=True)
Cost_Revenue_Centre = models.CharField(max_length=100, blank=True, null=True)
Product_Code = models.CharField(max_length=100, blank=True, null=True)
Product_Text = models.CharField(max_length=100, blank=True, null=True)
Account = models.CharField(max_length=100, blank=True, null=True)
Progcse = models.CharField(max_length=100, blank=True, null=True)
Budyear = models.CharField(max_length=100, blank=True, null=True)
# courses = models.ManyToManyField(Course, through="Material") # performance issue
# org_id = models.UUIDField()
# return canonical url for an object
def get_absolute_url(self):
kwargs = {
'slug': self.slug,
'pk': self.id,
}
return reverse('bms:book_detail', kwargs=kwargs)
def save(self, *args, **kwargs):
value = self.title
self.slug = slugify(value, allow_unicode=True)
super().save(*args, **kwargs)
# __str__ method is used to override default string returned by an object
def __str__(self):
return self.title
#property
def retail_price_display(self):
if self.retail_price:
return "{} ${}".format(self.retail_price_cur, self.retail_price)
return ""
class Meta:
ordering = ['-modified']
class ContentChecklist(BaseModel):
slug = models.SlugField(editable=False, max_length=20)
discipline = models.ForeignKey(Discipline, on_delete=models.CASCADE)
course_code = models.CharField(max_length=190, blank=True, null=True)
course_title = models.CharField(max_length=190, blank=True, null=True)
#type = models.CharField(max_length=2, choices=(('PT', 'Part Time'), ('FT', 'Full Time'), ('OL', 'Online')))
type = models.CharField(max_length=190, blank=True, null=True)
semester = models.ForeignKey(Semester, on_delete=models.CASCADE)
# hop = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(max_length=20, default=DRAFT, choices=MATERIAL_STATUS_CHOICES)
remark = models.CharField(max_length=190, blank=True, null=True)
postgraduate_course = models.CharField(max_length=190, blank=True, null=True)
Presentation_pattern = models.CharField(max_length=190, blank=True, null=True)
class Meta:
unique_together = ('discipline', 'course_code', 'type', 'semester')
ordering = ('semester', 'discipline', 'type', )
def save(self, *args, **kwargs):
if not self.pk: # generate slug value
value = str(self.discipline.name) + "-" + str(self.semester)
self.slug = slugify(value, allow_unicode=True)
super().save(*args, kwargs)
def get_absolute_url(self):
kwargs = {
'slug': self.slug,
'pk': self.pk,
}
return reverse_lazy('bms:cc_detail', kwargs=kwargs)
def __str__(self):
return "{} {} {} - Content Checklist".format(self.discipline, self.type, self.semester)
#property
def total_titles(self):
return self.material_set.count()
#property
def total_course(self):
return self.material_set.values('semester_course_id').distinct().count()
# return self.material_set.filter(semester_course__semester=self.semester,
# semester_course__course__in=self.discipline.course_set.all()).count()
# to contain list of Title that will involve in a Tender Exercise
# titles from 7 publisher will automatically out from TE
class TenderExercise(TimeStampedModel):
slug = models.SlugField(default='', editable=False, max_length=20)
from_year = models.CharField(max_length=20) # from semester year
from_month = models.CharField(max_length=20, choices=MONTH_CHOICES)
to_year = models.CharField(max_length=20) # to semester year
to_month = models.CharField(max_length=20, choices=MONTH_CHOICES)
materials = models.ManyToManyField(Material)
status = models.CharField(max_length=20, default=DRAFT, editable=False)
vendor = models.CharField(max_length=120, blank=True, null=True) # this is winning vendor
def save(self, *args, **kwargs):
if not self.pk: # generate slug value
value = self.from_month + self.from_year + "-" + self.to_month + self.to_year
self.slug = slugify(value, allow_unicode=True)
super().save(*args, kwargs)
#property
def total_titles(self):
return len(self.materials)
class Task(BaseModel):
name = models.CharField(max_length=120)
description = models.CharField(max_length=190, blank=True, null=True)
category = models.CharField(max_length=120, choices=CATEGORY_CHOICES)
start_date = models.DateTimeField(auto_now_add=True)
end_date = models.DateTimeField(null=True, blank=True)
# initiator => refer to the creator of the BaseModel
# assignee should be multiple, to create TaskUser table for this
assignee_hop = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE, related_name='assignee_hop')
assignee_hop2 = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE, related_name='assignee_hop2')
assignee_executive = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE, related_name='assignee_executive')
assignee_executive2 = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE, related_name='assignee_executive2')
assignee_executive3 = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE, related_name='assignee_executive3')
status = models.CharField(max_length=20)
def __str__(self):
to_tz = timezone.get_default_timezone()
return "{} task: {} is due on {}".format(self.category, self.name, self.end_date.astimezone(to_tz).strftime("%Y-%m-%d %H:%M:%S"))
class TaskData(models.Model):
task = models.ForeignKey(Task, on_delete=models.CASCADE)
name = models.CharField(max_length=64)
value = mod
els.CharField(max_length=190)
...
How could I quickly fix this problem?
Depending what your query is, it seems like you need to change the size of the column in MySQL. SEE: stackoverflow question MySQL varchar index length. Look at this link to see how many bytes a utf8 character can be Max. bytes in a UTF-8 char?.
It seems like you can alter the table right? So if you had something like
CREATE TABLE `test`.`my_table` (
`my_table_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`my_varchar_column` VARCHAR(768) NULL,
`my_indexed_column` VARCHAR(768) NULL,
PRIMARY KEY (`my_table_id`),
INDEX `index2` (`my_indexed_column` ASC) VISIBLE);
you might need to alter the table column in a manner similar to this:
ALTER TABLE `test`.`my_table`
CHANGE COLUMN `my_varchar_column` `my_varchar_column` VARCHAR(1024) NULL DEFAULT NULL ,
CHANGE COLUMN `my_indexed_column` `my_indexed_column` VARCHAR(2048) NULL DEFAULT NULL ;
NOTE that according to the link about utf-8 characters, I initially set the size of the column to be 768 utf-8 characters, which at a maximum; would be 3027 bytes.
If you need to alter a bunch of tables the following example is an option to get started. THIS IS JUST SIMPLE EXAMPLE OF WHAT YOU CAN DO WITH GROUP_CONCAT, YOU WILL NEED TO MODIFY IT TO MEET YOUR NEEDS - AND BE CAREFUL.
set session group_concat_max_len = 1024 * 1024 * 124;
select
group_concat(
concat(
'alter `', table_name, '` CHANGE COLUMN `', column_name, '` `', column_name, '` VARCHAR(1024);'
)
separator '\r\n'
) as stmt
from
information_schema.columns
where
table_schema = 'your_database_name_here'
and
table_name in ('your', 'list', 'of', 'tables', 'to', 'alter', 'here')
and
data_type like 'varchar'
and
CHARACTER_MAXIMUM_LENGTH < 255; # You don't need this line, it's just an example
Then follow these 6 simple steps
Make the adjustments as 'quoted' in the query (then run it)
Copy the result to the clipboard
Paste the result into a new query tab
Examine the script, MAKE SURE IT IS WHAT YOU WANT
Then make sure it is what you want
Then delete it because I don't want to be responsible for giving you the script to alter a bunch of tables that shouldn't have been altered.
Again... the above sql is just a glimpse at what you probably need to do.

How to Get Data Join Django Rest Framework

I want to join two tables,
i have model :
Employee :
class Employee(models.Model):
employee_identity = models.CharField(max_length=255, blank=True, null=True)
full_name = models.CharField(max_length=255, blank=True, null=True)
place_birth = models.CharField(max_length=255, blank=True, null=True)
date_birth = models.DateField(blank=True, null=True)
role = models.CharField(max_length=255, blank=True, null=True)
no_hp = models.CharField(max_length=255, blank=True, null=True)
address = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'employee'
Penalty :
class Penalty(models.Model):
employee = models.ForeignKey(Employee,on_delete=models.CASCADE)
type = models.CharField(max_length=255, blank=True, null=True)
start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
doc = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'penalty'
My EmployeeSerializer :
class EmployeeSerializer (serializers.ModelSerializer):
class Meta:
model = Employee
fields = '__all__'
My PenaltySerializer:
class PenaltySerializer (serializers.ModelSerializer):
class Meta:
model = Penalty
fields = ('employee','type','start_date','end_date')
My expected Penalty result :
"results": [
{
"employee": 14871,
"type": "low",
"start_date": "2018-10-15",
"end_date": "2018-10-16",
"employee_identity": "A1738129",
"full_name": "Full name here",
"role": "staff"
}
]
I have tried to using this in my serializer
class PenaltySerializer (serializers.ModelSerializer):
a = EmployeeSerializer(many=True,read_only=True)
class Meta:
model = Penalty
fields = ('employee','type','start_date','end_date','a')
but the result of 'a' not showed up.
I think this might help
class PenaltySerializer (serializers.ModelSerializer):
employee_identity = serializers.CharField(source="employee.employee_identity")
full_name = serializers.CharField(source="employee.full_name")
role = serializers.CharField(source="employee.role")
class Meta:
model = Penalty
fields = (
'employee',
'type',
'start_date',
'end_date',
'employee_identity',
'full_name',
'role'
)
You can do something like this in your serializer:
class PenaltySerializer (serializers.ModelSerializer):
employee = serializers.SerializerMethodField()
class Meta:
model=Penalty
fields = '__all__'
def get_employee(self, object):
return EmployeeSerializer(object.employee.all(), many=True).data

Require multiple entries for "Item", Django Admin

I want to enter multiple entries for "item" under one "session_title" - and I think I understand I need a ManyToOne relationship (set with ForeignKey) but mysite/admin isn't showing multiple entries available? I am using DjangoAdmin to administer my app.
Edit/Add: I know there's a step I'm missing. I'm hoping for someone to send me there.
class Item(models.Model):
item_name = models.TextField(unique=True)
class Meta:
managed = True
db_table = 'item'
def __str__(self):
return self.item_name
class SessionLog(models.Model):
date = models.DateField()
session_title = models.TextField(blank=True, null=True)
campaign = models.OneToOneField(Campaign, models.DO_NOTHING, default="1")
chapter = models.OneToOneField(Chapter, models.DO_NOTHING, default="1")
scene = models.OneToOneField(Scene, models.DO_NOTHING, default="1")
character = models.OneToOneField(Character, models.DO_NOTHING, default="1")
location = models.OneToOneField(Location, models.DO_NOTHING, blank=True, null=True)
npc = models.OneToOneField(Npc, models.DO_NOTHING, blank=True, null=True)
monster = models.OneToOneField(Monster, models.DO_NOTHING, blank=True, null=True)
item = models.ForeignKey(Item, models.DO_NOTHING, blank=True, null=True)
loot_pp = models.IntegerField(blank=True, null=True)
loot_gp = models.IntegerField(blank=True, null=True)
loot_ep = models.IntegerField(blank=True, null=True)
loot_sp = models.IntegerField(blank=True, null=True)
loot_cp = models.IntegerField(blank=True, null=True)
session_xp = models.IntegerField(blank=True, null=True)
session_strongstart = models.TextField(blank=True, null=True)
session_secrets = models.TextField(blank=True, null=True)
session_clues = models.TextField(blank=True, null=True)
session_notes = models.TextField(blank=True, null=True)
class Meta:
managed = True
db_table = 'session_log'
def __str__(self):
return self.session_title
Could someone point me in the right direction? Thank you, in advance.
Yep, you're on the right track.
Change
item = models.ForeignKey(Item, models.DO_NOTHING, blank=True, null=True)
to
items = models.ManyToManyField(Item, on_delete=models.DO_NOTHING)
and in your admin, declare an Inline class:
class ItemInline(admin.TabularInline):
pass
class SessionLogAdmin(admin.ModelAdmin):
inlines = [ItemInline]

Unknown column 'userprofile.id' in 'field list

I ma getting this error while calling save method. the error is Unknown column 'userprofile.id' in 'field list
class Userprofile(models.Model):
user = models.OneToOneField(User)
profile_id = models.IntegerField(db_column='profile_id') # Field namemade lowercase.
f_name = models.CharField(max_length=45, blank=True, null=True)
middle_name = models.CharField(max_length=45, blank=True, null=True)
l_name = models.CharField(max_length=45, blank=True, null=True)
dob = models.DateField(db_column='DOB', blank=True, null=True) # Field namemade lowercase.
contact_number = models.IntegerField(blank=True, null=True)
email = models.CharField(max_length=45, blank=True, null=True)
joining_date = models.DateField(db_column='Joining_date', blank=True, null=True) # Field name made lowercase.
temp_address = models.CharField(max_length=45, blank=True, null=True)
permanant_add = models.CharField(db_column='Permanant_add', max_length=45, blank=True, null=True) # Field name made lowercase.
user_image = models.CharField(max_length=45, blank=True, null=True)
gender_idgender = models.ForeignKey(Gender, models.DO_NOTHING, db_column='gender_idgender')
class Meta:
managed = False
db_table = 'userprofile'
unique_together = (('profile_id', 'gender_idgender'),)
This is my model
“_id” is suffix syntax in django query,You'd better not use it as a field name in your model。

Sum of a column with group by in django

I need some help with this sql query that I am trying to run with django orm model.
SELECT SUM(CAPITAL) AS PRODUCT_CAPITAL, PRODUCT FROM CAPITAL_SHEET
WHERE CLIENT_ID = 'X1234'
GROUP BY PRODUCT
I did this
CapitalSheet.objects.filter(client_id="X1234").values("product").annotate(Sum("capital"))
This is what I am getting as a result in json:
[
{
"product": "product1"
},
{
"product": "product2"
}
]
I was expecting this as output :
[
{
"product": "product1",
"capital": 1234.00
},
{
"product": "product2",
"capital": 1234.00
}
]
here is my view:
class CapitalListView(ListAPIView):
serializer_class = CapitalSheetSerializer
def get_queryset(self):
return CapitalSheet.objects.filter(client_id="X1234").values("product").annotate(Sum("capital"))
Here are my models:
class CapitalSheet(models.Model):
log_id = models.AutoField(db_column='LOG_ID', primary_key=True)
client_id = models.CharField(db_column='CLIENT_ID', max_length=25)
capital = models.DecimalField(db_column='CAPITAL', max_digits=10, decimal_places=2, blank=True, null=True)
payout_booked_profit = models.DecimalField(db_column='PAYOUT_BOOKED_PROFIT', max_digits=10, decimal_places=2, blank=True, null=True)
voucher_number = models.CharField(db_column='VOUCHER_NUMBER', max_length=45, blank=True, null=True)
ledger_date = models.DateField(db_column='LEDGER_DATE', blank=True, null=True)
amount = models.DecimalField(db_column='AMOUNT', max_digits=10, decimal_places=2, blank=True, null=True)
product = models.CharField(db_column='PRODUCT', max_length=45, blank=True, null=True)
transaction_type = models.CharField(db_column='TRANSACTION_TYPE', max_length=45, blank=True, null=True)
sebi_payin_flag = models.IntegerField(db_column='SEBI_PAYIN_FLAG', blank=True, null=True)
dividend_payout_flag = models.IntegerField(db_column='DIVIDEND_PAYOUT_FLAG', blank=True, null=True)
My serializer:
class CapitalSheetSerializer(serializers.ModelSerializer):
class Meta:
model = CapitalSheet
fields = ['capital','product']
What am i doing wrong here ?
try it, add name for annotate column:
CapitalSheet.objects.filter(
client_id="X1234"
).values("product").annotate(capital=Sum("capital"))
# ^^^^^^^