Как обновить профиль другого пользователя, если вы вошли в систему как владелец?

В настоящее время я вошел в систему как владелец и хочу обновить поля клиентов в базе данных. Но форма не обновляется или показывает данные в виде заполнителя, потому что модель пользователя расширила модель клиента и, следовательно, модель клиента не имеет собственных полей. Как мне получить экземпляр User модели Customer в UpdateView?/Как мне обновить клиента?

views.py

class CustomerUpdateView(OwnerAndLoginRequiredMixin, generic.UpdateView):
    template_name = "customer_update.html"
    form_class = CustomerModelForm
    queryset = Customer.objects.all()

    def get_success_url(self):
        return "/customers"

models.py

class Customer(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.user.username

class User(AbstractUser):
    is_owner = models.BooleanField(default=True)
    is_agent = models.BooleanField(default=False)
    is_customer = models.BooleanField(default=False)

forms.py

class CustomerModelForm(forms.ModelForm):
class Meta:
    model = User
    fields = (
        'email',
        'username',
        'first_name',
        'last_name',
    )

Итак, на данный момент я должен предположить несколько вещей... Допустим, у вас есть ListView для вывода списка клиентов.

views.py файл:

class CustomerListView(OwnerAndLoginRequiredMixin, generic.ListView):
     template_name = "customer_update.html"
     queryset = Customer.objects.all()
     context_object_name = 'customers'

urls.py файл:

urlpatterns = [
     ...
     path('customers/', CustomerListView.as_view(), name='customers'),
     path('update-customer/<int:pk>/', CustomerUpdateView.as_view(), name='update-customer'),
     # You can pass whatever customer related info you wish via url, I'm just using id as a simply demo.
     ...
]

html файл:

{% for customer in customers %}
     # Displaying other related info per customer

     # Link to click to update a particular customer profile: passing the customer pk via url
     <a href="{% url 'update-customer' customer.pk %}"> Update {{ customer.user.username|title }} Profile </a>
{% endfor %}

Возврат к файлу views.py:

class CustomerUpdateView(OwnerAndLoginRequiredMixin, generic.UpdateView):
     template_name = "customer_update.html"
     form_class = CustomerModelForm
     # context_object_name = 'customer'
     # queryset = Customer.objects.all() # not needed here

     # You can use the get_object() on the class to grab the customer object by the pk passed via url
     def get_object(self, queryset=None):
          customer_pk = self.kwargs.get('pk', None)

          return get_object_or_404(Customer, pk=customer_pk)

     # Also, you could use the get_context_data() to set the form values before rendering on the page
     def get_context_data(self, **kwargs):
          context = super().get_context_data(**kwargs)
          
          customer = self.get_object()  # -> returns a customer object

          # creating a dictionary to use to initialize the form: accessing the user information on the customer
          data = {
               'username': customer.user.username,
               'first_name': customer.user.first_name,
               'last_name': customer.user.last_name,
               'email': customer.user.email,
          }

          form = self.form_class(initial=data, instance=customer.user) # updated here too

          context['form'] = form  # -> updating the class view context dictionary
          return context

     def get_success_url(self):
          return "/customers"

Теперь в пределах customer_update.html:

<form method="POST">
     <div>
          {{ form.username }}

          {{ form.email }}

          {{ form.first_name }}

          {{ form.last_name }}
     </div>
     
     <input type="submit" value="Update"/>
</form>

Идеально, это должно отображать информацию о клиенте в форме.

UPDATES

Для обработки и сохранения отправки формы можно использовать post() на update-view. Вы можете добавить к CustomerUpdateView:

# Use the post method to handle the form submission
def post(self, request, *arg, **kwargs):

     # Should set the user instance on the form
     customer = self.get_object()
     form = self.form_class(request.POST, instance=customer.user)  # updated here too
     
     if form.is_valid():
          form.save()

          return redirect('to any path of your choice') # Redirect upon submission if necessary
     else:
          print(form.errors)  # To see the field(s) preventing the form from being submitted

     # Passing back the form to the template
     return render(request, self.template_name, {'form': form})
Вернуться на верх