Reputation: 27
In the view function, I redirect when making a post-request to refer-urk, to which I pass the id of the saved class instance, however, this id is lost and I get 404 Not Found.
models.py:
class Position(models.Model):
position_name = models.CharField(max_length=255, blank=True, verbose_name='Position')
created_by = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='user by', blank=True, null=True)
date_create = models.DateTimeField(auto_now_add=True)
date_update = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['date_create']
def __str__(self):
return self.position_name
class Contacts(models.Model):
pos = models.ForeignKey('Position', blank=True, null=True, on_delete=models.SET_NULL, verbose_name='Position')
contact_label = models.CharField(max_length=100, blank=True, verbose_name='Contact label')
contact_value = models.CharField(max_length=255, blank=True, verbose_name='Contact value')
def __str__(self):
return self.contact_label
forms.py:
class CreateCVContactForm(forms.ModelForm):
class Meta:
model = resume.models.Contacts
fields = (
'contact_label',
'contact_value'
)
In views.py usnig def createcvcontacts i do redirect for POST-request and pas id of saved object instance to url and then with HTMX i get this id in def ditailcontact which renders detail info abot object instance and pass context to contact_detail.html template:
views.py:
@login_required(login_url='/users/login/')
def create_cv_contacts(request, pk):
''' functions for working with models.Contacts '''
position = Position.objects.get(id=pk)
contacts = Contacts.objects.filter(pos=position)
form = CreateCVContactForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
contact = form.save(commit=False)
contact.pos = position
contact.save()
return redirect("resume:detail-contact", pk=contact.id) # here this redirect
else:
return render(request, "resume/partials/contact_form.html", context={
"form": form
})
context = {
"form": form,
"position": position,
"contacts": contacts,
'title': 'Add contacts'
}
return render(request, "resume/create_cv_contacts.html", context)
@login_required(login_url='/users/login/')
def update_contact(request, pk):
contact = Contacts.objects.get(id=pk)
form = CreateCVContactForm(request.POST or None, instance=contact)
if request.method == "POST":
if form.is_valid():
form.save()
return redirect("resume:detail-contact", pk=contact.id)
context = {
"form": form,
"contact": contact
}
return render(request, "resume/partials/contact_form.html", context)
@login_required(login_url='/users/login/')
def delete_contact(request, pk):
contact = get_object_or_404(Contacts, id=pk)
if request.method == "POST":
contact.delete()
return HttpResponse("")
return HttpResponseNotAllowed(
[
"POST",
]
)
@login_required(login_url='/users/login/')
def detail_contact(request, pk):
contact = get_object_or_404(Contacts, id=pk)
context = {
"contact": contact
}
return render(request, "resume/partials/contact_detail.html", context)
@login_required(login_url='/users/login/')
def create_contact_form(request):
form = CreateCVContactForm()
context = {
"form": form
}
return render(request, "resume/partials/contact_form.html", context)
urls.py, url name is detail-contact i get this id of saved instance:
app_name = 'resume'
urlpatterns = [
path('', views.main_page, name='main_page'),
path('list/', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.GetResume.as_view(), name='get_person'),
path('create-cv-pers-data/', views.create_cv_personal_data, name='create_cv_personal_data'),
# path('create-cv-position/', views.CreateCVPosition.as_view(), name='create_cv_position'),
path('create-cv-position/', views.create_cv_position, name='create_cv_position'),
# paths for working with Contacts objects
path('create-cv-contacts/<int:pk>', views.create_cv_contacts, name='create_cv_contacts'), # here is url for GET-request in def create_cv_contacts
path('htmx/contact/<pk>/', views.detail_contact, name="detail-contact"), # here i get this id of saved instance
path('htmx/contact/<pk>/update/', views.update_contact, name="update-contact"),
path('htmx/contact/<pk>/delete/', views.delete_contact, name="delete-contact"),
path('htmx/create-contact-form/', views.create_contact_form, name='create-contact-form'),
]
templates:
createcvcontacts.html*,* this template is rendered during at runtime GET-request of def create_cv_contatcs:
{% extends 'resume/base.html' %}
{% load static %}
{% block content %}
<div class="md:flex md:items-center md:justify-between">
<div class="flex-1 min-w-0">
<h2 class="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate">
Add contacts for {{ position.position_name }}
</h2>
</div>
<div class="mt-4 flex md:mt-0 md:ml-4">
<button type="button" hx-get="{% url 'resume:create-contact-form' %}" hx-target="#contactforms" hx-swap="beforeend"
class="ml-3 inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Add form
</button>
</div>
</div>
<div id="contactforms" class="py-5 mt-5"></div>
<div class="mt-5 py-5 border-t border-gray-100">
{% for contact in contacts %}
{% include "resume/partials/contact_detail.html" %}
{% endfor %}
</div>
{% endblock %}
contact_detail.html:
<div hx-target="this" class="mt-3 py-3 px-3 bg-white shadow border border-gray-100">
<h3 class="text-lg leading-6 font-medium text-gray-900">
Contact label: {{ contact.contact_label }}
</h3>
<p class="text-gray-600">Contact: {{ contact.contact_value }}</p>
<div class="mt-2">
<button hx-get="{% url 'resume:update-contact' contact.id %}" hx-swap="outerHTML"
class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Update
</button>
<button hx-post="{% url 'resume:delete-contact' contact.id %}" hx-swap="outerHTML swap:1s"
class="ml-2 inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500">
Delete
</button>
</div>
</div>
Here is headers of request (the URL doesn't have id):
And here is the mesage from console:
Not Found: /create-cv-contacts/
[08/May/2023 21:41:26] "POST /create-cv-contacts/ HTTP/1.1" 404 4149
Here i use HTMX. I got tutorial of this one from this video https://www.youtube.com/watch?v=KVq_DjIfnBo and here all is work.
I didn't find solution of my problem in Stack Owerflow, please help me
Upvotes: 0
Views: 125
Reputation: 740
Please post the partial HTML you are using in "resume/partials/contact_form.html".
My guess is you are doing an hx-post
in there, but you're not including the appropriate position.id variable inside the hx-post
value. E.g. it should look like the below:
<button hx-post="{% url 'resume:create_cv_contacts' position.id %}" ...>
Create
</button>
I suspect the position.id is missing from the above.
You will probably need to include this position.id dynamically, in which case you will need to adjust the contact_form view, url and templates as follows:
Change the Add Form button as below:
<button type="button" hx-get="{% url 'resume:create-contact-form' position.id %}" ...>
Add form
</button>
Change the 'create-contact-form' URL as follows:
path('htmx/create-contact-form/<int:pk>/', views.create_contact_form, name='create-contact-form')
Change the create_contact_form View as follows:
@login_required(login_url='/users/login/')
def create_contact_form(request, pk):
form = CreateCVContactForm()
position = {"id": pk} # add this
context = {
"form": form,
"position": position, # add this
}
return render(request, "resume/partials/contact_form.html", context)
Now make sure you have this position.id inside your hx-post
on the create_form.html itself (as at the top of this post), and hopefully it should work. Let me know if not.
Upvotes: 0