1

The pages made of existing php are being changed to python and Django.

Existing Query

Select
    l.lawyer_idx,
    l.lawyer_email,
    lp.lawyer_profile_path,
    lp.lawyer_profile_name,
    lc.lawyer_company_name,
    lc.lawyer_company_address,
    lc.lawyer_detail_address,
    l.lawyer_agent
from lawyer l
left join lawyer_profile lp on l.lawyer_idx = lp.lawyer_idx
left join lawyer_company lc on l.lawyer_idx = lc.lawyer_idx
order by l.register_date desc;

I made each table at models.py

    models.py

    class Lawyer(models.Model):
     lawyer_idx = models.AutoField('ID', primary_key=True)
      lawyer_email = models.CharField('E-mail', unique=True, max_length=200)
     lawyer_agent = models.CharField(max_length=1, blank=True, null=True)

    class Meta:
       managed = False
       db_table = 'lawyer'


    class LawyerProfile(models.Model):
     lawyer_idx = models.AutoField('ID', primary_key=True)
     lawyer_profile_path = models.CharField(max_length=200, blank=True, null=True)
   lawyer_profile_name = models.CharField(max_length=100, blank=True, null=True)
.................

    class LawyerCompany(models.Model):
     lawyer_idx = models.AutoField('ID', primary_key=True)
     lawyer_company_name = models.CharField(max_length=100)
    ...............

We would like to place the following query into the list_display portion of Django Admin.py Is there any way to show the data that did join in sql?

    Admin.py
    from django.contrib import admin
    from .models import Lawyer, LawyerCompany, LawyerProfile

    @admin.register(Lawyer)
    class LawyerAdmin(admin.ModelAdmin):

       list_per_page = 100
       **list_display = ['lawyer_idx', 'lawyer_email', 
'lawyer_agent', 'lawyer_profile_path', 'lawyer_profile_name', 'lawyer_company_name']**

1 Answers1

0

You could add the query as a raw sql query, but that wouldnt make much use of Django's ORM then.

You are not explicitly defining any relationships on your models, so Django doesn't know about how your models relate.

If lawyer_idx references the lawyer you could change the field to a OneToOneField/ForeignKey (an AutoField is probably the wrong choice here anyways, as the values should correspond to those in the Lawyer model and not be auto-generated). Also have a look at the documentation for one-to-one and many-to-one relationships.

class LawyerProfile(models.Model):
     lawyer = models.OneToOneField(Lawyer, primary_key=True, 
         db_column="lawyer_idx", related_name="profile")

Django should perform the joins automatically when accessing the related data; on a Lawyer instance you can then access the profile via its related_name .profile. In the list_display option you can use the double underscore syntax to access related data:

list_display = ['lawyer_idx','lawyer_agent', 'profile__lawyer_profile_path']
list_select_related = ['profile']

If you add the list_select_related option Django will already join the specified table beforehand, so no additional queries are performed when accessing the related data.

Bernhard Vallant
  • 49,468
  • 20
  • 120
  • 148
  • thanks~!I got a problem. File "C:\workspace\bhsn\models.py", line 603, in LawyerProfile lawyer_idx = models.OneToOneField(Lawyer, primary_key=True, db_column='lawyer_idx', related_name='profile') TypeError: __init__() missing 1 required positional argument: 'on_delete' – user2648080 Mar 07 '19 at 05:26
  • Yes you need to add an `on_delete=models.CASCADE` https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.ForeignKey.on_delete – Bernhard Vallant Mar 07 '19 at 09:06
  • i try this!!!!!!model.py class LawyerCompany(models.Model): lawyer_idx = models.OneToOneField(Lawyer, primary_key=True, db_column="lawyer_idx", related_name="profile", on_delete='models.CASCADE') lawyer_company_name = models.CharField(max_length=100) AND admin.py -> list_display = ('lawyer_idx', 'profile__lawyer_company_name',) BUT!!!!!!!!!ERRORS: : (admin.E108) The value of 'list_display[6]' refers to 'profile__lawyer_company_name', which is not a callable, an attribute of 'LawyerAdmin', or an attribute or method on 'bhsn.Lawyer'. – user2648080 Mar 15 '19 at 00:57
  • Sorry I overlooked that this doesnt seem to work with the `OneToOneField`, but you can do it like in this question https://stackoverflow.com/questions/20652949/access-from-django-admin-list-display-a-value-from-a-one-to-one-table – Bernhard Vallant Mar 15 '19 at 13:37