Reputation: 1932
I would like to pass a variable from one view to another in Django and am not sure of the best method.
The "defaultCreateView" below is a form that makes a new database entry and has a required field that I want to be filled automatically (device_id). So my thought is I could pass it through in the URL. This form is accessed using the button shown in my template below. So the idea is that the first view passes the variable to the template where the button is, then this button adds the device_id to the URL via the href.
Is there a much easier/better way to accomplish this?
Thanks in advance for any help.
urls.py
urlpatterns = [
path('<int:pk>/edit/', defaultUpdateView.as_view(), name='default_edit'),
path('<int:pk>/', defaultDetailView.as_view(), name='default_detail'),
path('<int:pk>/delete/', defaultDeleteView.as_view(), name='default_delete'),
path('<int:device>', DefaultsListView.as_view(), name='Default_Listview'),
path('<int:device>/new/', defaultCreateView.as_view(), name='default_new'),
path('Defaultsapidata/', apiDefaultsListView.as_view(), name='Defaults_apidata_list'),
path('<int:pk>/changedefaults/', changeDefaultsViewSingle.as_view()),
]
Views.py
class DefaultsListView(LoginRequiredMixin,ListView):
model = models.DefaultDMLSProcessParams
template_name = 'defaults_list.html'
login_url = 'login'
def get_queryset(self):
return super(DefaultsListView, self).get_queryset().filter(device_id=self.kwargs['device'])
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
deviceID = self.kwargs['device']
context['deviceID'] = deviceID
return context
class defaultCreateView(LoginRequiredMixin,CreateView):
model = models.DefaultDMLSProcessParams
template_name = 'default_new.html'
fields= ['defaultParamDescrip','processType','processNotes',]
login_url = 'login'
def form_valid(self, form):
form.instance.customerTag = self.request.user.customerTag
form.instance.device_id = self.kwargs['device']
return super().form_valid(form)
defaults_list.html
<a class="btn btn-primary btn-lg"
href="{% url 'default_new' {{deviceID}} %}" role="button"> Add New Default Parameter</a>
EDIT I get a "NoReverseMatch at /defaults/41" when I try to access defaults_list.html, but this is solved when I change the URL of defaultCreateView to:
path('new/', defaultCreateView.as_view(), name='default_new'),
Upvotes: 2
Views: 5044
Reputation: 71
I had the same problem. I've made up my mind to pass an email into args in 'RegisterUserView' and then in 'CodeConfirmationUserView' retrieve this value in 'get_initial' method which obtains an 'email' from self.kwargs and then passes it into my template as an initial data.
views.py
class RegisterUserView(ConfirmationCodeMixin, ErrorMessageMixin, SuccessMessageMixin, CreateView):
model = get_user_model()
form_class = RegisterUserForm
template_name = 'users/register.html'
extra_context = {'title': 'Registration'}
success_message = "The confirmation code has been successfully sent!"
def form_valid(self, form):
try:
user = form.save(commit=False)
except UserNotInExternalResource as error:
messages.error(request=self.request, message=error)
return redirect(to=reverse_lazy(REGISTER_URL))
# ...
return redirect(to=reverse_lazy('users:code_confirmation', args=(user.email,)))
class CodeConfirmationUserView(ConfirmationCodeMixin, ErrorMessageMixin, SuccessMessageMixin, FormView):
model = get_user_model()
form_class = CodeConfirmationUserForm
template_name = 'users/code_confirmation.html'
extra_context = {'title': 'Registration'}
success_url = reverse_lazy('home')
success_message = "Registation and authentication have been successfully permormed!"
def post(self, request, *args, **kwargs):
# ...
def get_initial(self):
initial = super().get_initial()
initial['email'] = self.kwargs.get('email', '') # Set the initial value for the email field
return initial
code_confirmation.html
<div class="my-3">
<label class="w-150 me-2 align-top" for="{{ form.email.id_for_label }}">
{{ form.email.label }}
</label>
{{ form.email }}
</div>
<div class="my-3">
<label class="w-150 me-2 align-top" for="{{ form.confirmation_code.id_for_label }}">
{{ form.confirmation_code.label }}
</label>
{{ form.confirmation_code }}
</div>
urls.py
from django.urls import path
from users import views
app_name = "users"
urlpatterns = [
path('register/', views.RegisterUserView.as_view(), name='register'),
path('code_confirmation/<str:email>', views.CodeConfirmationUserView.as_view(), name='code_confirmation')
]
Now the default value for email will be displayed
Upvotes: 0
Reputation: 208
def update_project_filter(request):
...
selected_project_id = project_form.cleaned_data["Project_Name"].id
request.session['selected_project_id'] = selected_project_id
...
def update_project(request):
...
selected_project_id = request.session.get('selected_project_id')
...
Assuming you've activated "django.contrib.sessions.middleware.SessionMiddleware"
Upvotes: 10