Как изменить первичный ключ, передаваемый в представление обновления в django?

Я хочу изменить первичный ключ, передаваемый в представление обновления из шаблона. Позвольте мне объяснить. Вот мой шаблон:

<a href="{% url 'new_url' model_instance.pk %}">
    {{ model_instance.username }}
</a>

Это model_instance является экземпляром в цикле for контекстной переменной model_instances в представлении списка. Этот первичный ключ экземпляра_модели затем будет отправлен в следующее представление:

class UserUpdateView(generic.UpdateView):
    template_name = "leads/update.html"
    queryset = User.objects.all()
    context_object_name = "user"
    form_class = UserUpdateForm

    def get_success_url(self):
        return reverse("some-url")

Однако проблема в том, что первичный ключ, который я отправляю в UserUpdateView, является первичным ключом для модели model_instance, а не для модели User. Более того, между этими двумя моделями нет связи типа "один-к-одному". Однако сходство есть. Обе модели model_instance и user имеют по одному полю username, которые одинаковы.

Другими словами, мне нужно сначала получить model_instance.username, а затем запросить модель User, чтобы найти экземпляр user с тем же username, который я хочу обновить. На данный момент UserUpdateView просто получает первичный ключ для model_instance в шаблоне, а это не то, что я хочу. Я надеюсь, что вы, ребята, сможете помочь мне с этой проблемой, и, пожалуйста, оставляйте любые вопросы, которые у вас есть. Спасибо.

Это недостаточно интуитивно понятно, но да, это возможно. Также хорошо упомянуть, что вы определяете атрибут queryset в представлении, если вы хотите обновить только один объект, то это не обязательно. Вы можете переопределить метод get_object для этого :

class UserUpdateView(generic.UpdateView):
    template_name = "leads/update.html"
    # queryset = User.objects.all()
    context_object_name = "user"
    form_class = UserUpdateForm

    def get_success_url(self):
        return reverse("some-url")
    
    def get_object(self):
        # Here w'll retrieve the correct object to update
        
        # First we retrieve the username of the model_instance
        model_instance = ModelInstance.objects.get(pk=self.kwargs['pk'])
        username = model_instance.username  # Retrieve the username
        
        # After, retrieve the user with username=model_instance.username
        # Normally, the username must be unique per model_instance and per user. If not an error can be trowed.
        user = User.objects.get(username=username)
        # If username is not unique, try this approach
        # user = User.objects.filter(username=username).first()

        # Return the user object
        return user

Эта ссылка на шаблон :

<a href="{% url 'new_url' model_instance.pk %}">
    {{ model_instance.username }}
</a>

теперь будет указывать на пользователя для обновления, а не на экземпляр модели.

Подробнее о get_object

Поскольку model_instance и user имеют одинаковое имя пользователя, вы можете передать model_instance.username при генерации url и изменить UpdateView для указания slug_field = "username". Вам также придется изменить urlconfig, чтобы использовать "slug" вместо "pk" или добавить slug_url_kwarg = "pk" .

<a href="{% url 'new_url' model_instance.username %}">
    {{ model_instance.username }}
</a>
class UserUpdateView(generic.UpdateView):
    template_name = "leads/update.html"
    queryset = User.objects.all()
    context_object_name = "user"
    form_class = UserUpdateForm
    slug_field = "username"
    slug_url_kwarg = "pk"

    def get_success_url(self):
        return reverse("some-url")
Вернуться на верх