User.first_name

We would need to see your complete ModelAdmin class for that list_display to be able to answer that question.

On the same page with, or without, submitting the form (full-page refresh)?

If “with”, then you’re rerendering that page, using the selection made in the select box to add to your context for the next render.

If “without”, then that requires a JavaScript AJAX call to the server to request the desired data which you then inject into that field. The specifics on doing that are somewhat dependent upon what JavaScript framework you’re using in your application. (Doing this with bare JavaScript is going to be different than if you’re using jQuery, both of which are different than if you’re using React, etc.)

We would need to see your complete ModelAdmin class for that list_display to be able to answer that question.

As you will see, lastName and firstName are not fields. They are methods in the admin class. I am struggling to find a way to get these fields into the admin section. Is there some other way? I think that they need to be fields in the model to be able to sort. Is that correct?

admin.py

# ───────────────────────────────────────────────────────────────────────────────
# Boston Pizza Orders
# ───────────────────────────────────────────────────────────────────────────────
@admin.register(BostonPizzaOrder)
class BostonPizzaOrder(admin.ModelAdmin):
  
  # def firstName(self, obj):
  #   return obj.user_name.first_name

  # def lastName(self, obj):
  #     return obj.user_name.last_name
  
  def firstName(self, Profile):
    return Profile.user_name.firstName

  def lastName(self, Profile):
      return Profile.user_name.lastName

  # Fields and section appearing in the change list. Note: The fileds listed
  # here must be editible. orderSubmitted_Date is not and can't be listed here.
  # it can be in the list_display because it's only viewed.
  fieldsets = (
    ('Order Name and Order Number', {
      'fields': [('user_name', 'order_Number',)],
      # 'description': '%s' % TEXT,
    }),
    ('Pasta Choice', {
      'fields': [('bpPasta',)]
    }),
    ('Salad Choice', {
      'fields': [('bpSalad', 'bpSaladDressing'),
      # ('', '')
      ],
      # 'classes': ('collapse',), <collaps the Veggies section if you like>
    }),
    ('Drink Choice', {
      'fields': [('bpDrink')]
    }))

  radio_fields = {
  # 'user_name':admin.VERTICAL,
  'bpPasta':admin.VERTICAL,
  # '':admin.VERTICAL,
  'bpSalad':admin.VERTICAL,
  'bpSaladDressing':admin.VERTICAL,
  #   # 'cheese':admin.VERTICAL, # ManyToManyField
  #   'bread_size':admin.VERTICAL,
  #   # 'extra':admin.VERTICAL, # ManyToManyField
  #   'drink':admin.VERTICAL,
  #   'cookie':admin.VERTICAL,
  #   'chips':admin.VERTICAL,
   }

  list_display = (
  'user_name',
  'lastName',
  'firstName',
  'order_Number',
  'bpPasta',
  'bpSalad',
  'bpSaladDressing',
  'bpDrink',
  'orderSubmitted_Date',
  )
  ordering = ('user_name',)
  # ordering = ('lastName',)
  search_fields = ('bpPasta',)
  list_filter = ('order_Number',)

Excerpt from view.py : Please excuse all my notes in the file. I wanted to highlight the variable used in userSelection. I would like to add another variable to sort on last name. This is my problem. Where to get the last name from User or Profile. I think Profile allows more flexibility in that I can add more fields.

# ───────────────────────────────────────────────────────────────────────────────
# Boston Pizza Group Meal Order 
# ───────────────────────────────────────────────────────────────────────────────
@login_required(login_url='/login')
def BostonPizzaGroupOrder(request):
  submitted = False
  form = BostonPizzaGroupOrderForm(request.POST)
  if form.is_valid():
    instance = form.save(commit=False)
    instance.user_name = request.user.profile
    # instance.user_name = request.user.profile.lastName
    # user_name = request.user
    print('User: '  f'{ instance.user_name}')
    print('Profile Last Name: '  f'{ instance.user_name.lastName}')
    print('Profile first Name: '  f'{ instance.user_name.firstName}')
        
    # Returns a data dictionary.
    print('form.cleaned_data: ' f'{form.cleaned_data}')
        
    # Returns the actual value from the dictionary.
    userSelection = form.cleaned_data['order_Number']
    print('UserSelection: ' f'{userSelection}') 
        
    # This works too.
    # print(form.cleaned_data['order_Number']) 
        
    # Check to see if the form is bound, returns true if bound.
    print('form.is_bound: ' f'{form.is_bound}')
  
  OrderCount = BostonPizzaOrder.objects.all().filter(order_Number=userSelection).count
  print(userSelection)

  # lastName = user.user_name.first_name

  orderByNumber = BostonPizzaOrder.objects.all().filter(order_Number=userSelection).order_by('user_name')
  # orderByNumber = BostonPizzaOrder.objects.all().filter(order_Number=userSelection).order_by('bpPasta')
  
  return render(request, 'meals/BostonPizzaGroupOrder.html',
  {'title': 'Group Order',
    'MyOrders': orderByNumber, 
    'OrderCount': OrderCount,
    'form': form,
  })

Specifically, the section starting with:

Usually, elements of list_display that aren’t actual database fields can’t be used in sorting (because Django does all the sorting at the database level).

It covers precisely this situation.

Agreed, the work around must be to create a field in the model, correct?
If thats the case how do I do this? I don’t need to create a ‘new’ field for last name. The last name exists in both the User and Profile classes. How to I create a field in the model that captures the last name from the selected User or Profile?

Not correct. That section of the docs explains what needs to be done.

Specifically, the section starting with:
Usually, elements of list_display that aren’t actual database fields can’t be used in sorting (because Django does all the sorting at the database level).

However, if an element of list_display represents a certain database field, you can indicate this fact by using the display() decorator on the method, passing the ordering argument…example…

I interpret this to mean that there must be a field in the model. But I think you’re telling me this is incorrect. That it applies to the case where no field exists. In my case the method/function lastName in the ModelAdmin;

@admin.register(BostonPizzaOrder)
class BostonPizzaOrder(admin.ModelAdmin):

def lastName(self, Profile):
      return Profile.user_name.lastName

model.py

class BostonPizzaOrder(models.Model):
  
  user_name = models.ForeignKey(Profile,   
  on_delete=models.CASCADE,
  default=None, 
  null=True, 
  blank=True)

I hope I’m not frustrating you with my questions. I really appreciate your help.

Actually, as you’ve written this, you are correct. The element of list_display represents a database field. (As opposed to saying that the element is a database field.)
Yes, there must be a field in the model - but the field in the model does not need to be the field in the ModelAdmin method being used in list_display. In this case, the entry in the list_display attribute identifies a representation of a model field.

And, further down in that same section:

The ordering argument supports query lookups to sort by values on related models. This example includes an “author first name” column in the list display and allows sorting it by first name:

The example that follows this text and the example after that appear to be what you’re looking to achieve. (Do be aware that the two examples do differ - one shows the method being a method in the Model class, the other showing the method being in the ModelAdmin class. Both are legal, but have slightly different implications.)

Nope, no worries there. As long as you continue to demonstrate that you’re willing to do your share of the work with learning this (as you repeatedly have so far), I’m more than happy to keep trying to help.

Question along the same theme…
I have built a model Player that is populated with firstName, lastName and other elements. I have built a form where I can reference the Player object. I can’t quite figure out how get a charField to populate with the firstName of the Player. I would like to do this prior to posting the form. I’m sure this can be done but I’m not sure what lacking, my Python knowledge or my Django models/forms knowledge.
When creating a roster and saving the instance to the database the user would select the last name. Then I can sent row headers to any other value in the Player Class. Know what I mean. Like selecting a part number and having any other Class elements displayed before positing the order.
Hopefully I’ve asked the question correctly. Any help would be appreciated. I’ve poured over the model docs and can’t find any examples that speak to what I’m trying to accomplish. It seems trivial. I suspect I would have to create a Class method for each object. Getter’s I think. But I want to check with the experts first.
Thanks in advance.