Как изменить первичный ключ, передаваемый в представление обновления в 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")