I'm trying to show foreign key data as a drop down list, but we have a big data, the problem is it takes too long to load page that has the drop down field with the foreign key, is there a way to load it part by part?
here is my models.py
class Vistor(models.Model):
admin = models.ForeignKey(User,on_delete=models.PROTECT,default=1)
full_name = models.CharField(max_length=150,verbose_name=_('full name'))
dob = models.DateField(max_length=14,verbose_name=_('dob'))
city = models.ForeignKey(City,on_delete=models.CASCADE,verbose_name=_('city'))
class Meta:
constraints = [
models.UniqueConstraint(fields=['full_name','dob','city'],name='full_information')
]
def __str__(self):
return f'{self.full_name} - {self.city} - {self.dob}'
and here is my views.py
def add_new_post(request):
...
context = {
'form':form,
'room_number':room_number,
'cities':City.objects.all(),
'all_guests':Vistor.objects.all().order_by('-pk'), #the problem is here, has a big data
}
return render(request,'booking/add_booking.html',context)
and here is my templates
<div class="grid md:grid-cols-10 md:gap-5 child_formset_row" id="guests_no-${form_no}">
<div class="col-span-5 groupinput relative bglightpurple mt-2 rounded-xl">
<label class="text-white absolute top-1 mt-1 mr-2 text-xs">{% trans "full information" %}</label>
<select name="guestinfo-0" id="guestinfo-0" class="visitors w-full pr-2 pt-6 pb-1 bg-transparent focus:outline-none text-white">
<option value="-----">------</option>
{% for c in all_guests %}
<option value="{{ c.full_name }} - {{c.city}} - {{c.dob | date:'Y-m-d'}}">{{ c.full_name }} - {{c.city}} - {{c.dob | date:'Y-m-d'}}</option>
{% endfor %}
</select>
</div>
<div class="col-span-4 groupinput relative bglightpurple mt-2 rounded-xl">
<label class="text-white absolute top-1 mt-1 mr-2 text-xs">{% trans "reason" %}</label>
<input type="text" name="reason-0" id="reason-0" value="" required class="w-full pr-2 pb-1 pt-6 bg-transparent focus:outline-none text-white">
</div>
<button type='button' class="col-span-1 flex items-center justify-center groupinput relative bglightpurple mt-2 rounded-xl" onclick="remove_form(this,${form_no})"><i class="text-red-600 far fa-trash-alt"></i></button>
</div>
is there a way to load it part by part please ?
thank you so much for your helps ..
You can use django-autocomplete-light along with leveraging Django forms to display that element.
This gives a searchable as well as scrollable dropdown that loads your data with a pagination type of concept.
Related
i am looping through an array displaying songs I have uploaded into firebase. I am giving the user a button to edit the name of the song if they press the edit button. When button is pressed it show to edit details, however, except of only the one object expanding all of them expand to edit. How can I give each object its own version of the showForm Bool thanks.
Displaying songs:
<div v-for="song in watchSongs" :key="song.docID">
<div class="mt-[10px] border-solid border-2 border-gray-400 rounded-lg p-[5px] min-h-[40px]">
<p class="font-bold float-left">{{song.modifiedName}}</p>
<img #click.prevent="showForm = !showForm" src="#/assets/edit.png" alt="" class="w-[20px] float-right hover:cursor-pointer">
<img src="#/assets/close2.png" alt="" class="w-[20px] float-right hover:cursor-pointer">
<div v-if="this.showForm" class="pt-[30px]">
<p>song title</p>
<input type="text" placeholder="Enter Song Title" class="w-[100%] h-[30px] pl-[5px] mt-[10px] bg-transparent border-[1px] border-solid border-gray-300">
<p>Genre</p>
<input type="text" placeholder="Enter genre" class="w-[100%] h-[30px] pl-[5px] mt-[10px] bg-transparent border-[1px] border-solid border-gray-300">
<div class="flex mt-[20px] mb-[10px]">
<button class="bg-green-500 rounded-md w-[70px] mr-[5px]">Submit</button>
<button class="bg-gray-400 rounded-md w-[70px]">Go back</button>
</div>
</div>
</div>
The data:
export default {
name:"AppUploadDetails",
props: ['songs'],
data(){
return{
showForm:false,
}
},
computed:{
watchSongs(){
return this.songs;
}
}
}
Fixed by changed the v-if to v-if="song.showForm" and the click to #click.prevent="song.showForm"
Use an object to store your loop items, with the key being the docID.
Something like this:
showForm: {}
click.prevent="showForm[song.docID] = !showForm[song.docID]
I want to save after submitting all answers from a user of all questions related on a specific Quiz.
The logical is :
I've got Quiz, Questions. Question car link to Quiz and when I choose a quiz all questions link to are shown on webpage with javascript (design).
After submiting I need to get all checkbox checked and save into UserResponse.
Models
class Question(models.Model):
objects = None
question = models.CharField(max_length=200, null=True)
description = models.CharField(max_length=255, null=True)
question_pic = models.ImageField(upload_to='poll/', storage=fs, null=True)
choices = models.ManyToManyField(Answer, related_name='QuestionsChoices')
mandatory = models.BooleanField(default=True)
multiple = models.BooleanField(default=False)
randomize = models.BooleanField(default=False)
class Quiz(models.Model):
STATUS_CHOICES = (
(1, 'Draft'),
(2, 'Public'),
(3, 'Close'),
)
nom = models.CharField(max_length=200, null=False)
theme = models.ForeignKey(Theme, null=False, on_delete=models.CASCADE)
questions = models.ManyToManyField(Question, related_name='Quizs')
status = models.IntegerField(choices=STATUS_CHOICES, default=1)
published = models.DateTimeField(null=True)
date_added = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now_add=True)
class QuizInstance(models.Model):
objects = None
"""
A combination of user response and a quiz template.
"""
player = models.ForeignKey(User, on_delete=models.CASCADE)
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
start_quiz = models.DateTimeField(auto_now_add=True)
score = models.IntegerField(default=0)
complete = models.BooleanField(default=False)
class UserResponse(models.Model):
objects = None
"""
User response to a single question.
"""
quiz_instance = models.ForeignKey(QuizInstance, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
response = models.ManyToManyField(Answer, related_name="UserResponses")
time_taken = models.DateTimeField(auto_now_add=True)
time_taken_delta = models.DateTimeField(blank=True)
VIEWS (to show all questions from selected quiz)
def show_quiz(request, quiz_id):
try:
quiz = Quiz.objects.get(pk=quiz_id)
except:
messages.error(request, "Ce quiz n'existe pas ;)")
return redirect('poll:show-list')
context = {
'quiz': quiz,
}
return render(request, "poll/show_quiz.html", context)
# IF QUIZ SUBMITED, HERE I NEED TO SAVE ALL ANSWER GAVE BY USER INTO UserResponse
def answer_quiz(request):
context = {}
if request.method == 'POST':
quiz = Quiz.objects.get(pk=request.POST.get('id_quiz'))
player = request.user
quiz_player = QuizInstance.objects.filter(player=player, quiz=quiz)
if len(quiz_player) == 0:
quiz_instance = QuizInstance.objects.create(player=player, quiz=quiz)
else:
context = {
'error': True,
}
return render(request, "poll/answer_quiz.html", context)
TEMPLATES (HTML)
[...]
{% for question in quiz.questions.all %}
<fieldset class="p-4" style="max-width:720px; margin:0 auto;">
<question>
{{ forloop.counter }} - {{ question.question }}
{% if question.question_pic != "" and question %}
<div class="col-12 my-3 rounded-3" id="picQuestionDiv">
<img class="img-thumbnail rounded-3 p-2" src="/media/{{ question.question_pic }}" width="200" />
</div>
{% endif %}
</question>
<reponses class="d-grid gap-4" style="display:block !important; ">
{% if question|is_answer_pic %}
{% for reponse in question.choices.all %}
<input type="checkbox" hidden value="{{ reponse.id }}" name="reponse" id="reponse_{{ reponse.id }}" />
<reponse style="width:calc(50% - 8px + 4px); text-align:left !important;" class="col-6 mb-2 btn btn-reponse reponse" data-id="reponse_{{ reponse.id }}">
<div class="d-flex align-items-center rounded-3">
{% if reponse.answer_pic %}
<img class="card-img-top rounded-3 img-fluid mh-100 cover text-center" style="" src="/media/{{ reponse.answer_pic }}">
{% else %}
<i class="card-img-top rounded-3 mt-2 img-fluid mh-100 cover bi bi-eye-slash fs-1 text-center"></i>
{% endif %}
</div>
<div style="display:inline-block">
<span class="border border-secondary p-0 px-2 rounded-3 letter-reponse-pic bg-light text-secondary" style="">{{ forloop.counter0|show_letter }}</span>
<span class="">{{ reponse.answer }}</span>
</div>
</reponse>
{% endfor %}
{% else %}
{% for reponse in question.choices.all %}
<reponse style="width:calc(50% - 8px + 4px);" class="col-6 mb-2">
<div class="d-flex align-items-center rounded-3 border btn btn-outline-reponse p-2 reponse mb-2">
<span class="border border-secondary p-0 px-2 rounded-3 letter-reponse bg-light text-secondary">{{ forloop.counter0|show_letter }}</span>{{ reponse.answer }}
</div>
</reponse>
{% endfor %}
{% endif %}
</reponses>
<link class="" style="display: block;">
{% if not forloop.first %}
<a class="btn btn-secondary prev">Précédente</a>
{% endif %}
{% if not forloop.last %}
<a class="btn btn-secondary next">Suivante</a>
{% endif %}
{% if forloop.last %}
<button type="submit" class="btn btn-success next">Terminé !</button>
{% endif %}
</link>
</fieldset>
{% endfor %}
I know my method is not very clean ... I use form for Create Question, Quiz, etc ... but for showing Question I can't because need to show specific kind of checkbox if image, and other if not ... Anyway, here my need it just to retrive from POST submitting all data from quiz send by user And save it :)
Thanks for your help
I've started with HTMX and I want to use it to refresh part o page after pressing button on pop-up page. The button is adding clicking user as participant in an event. I going true tutorials and example which mostly present cases with forms and I don't know how to approach this update with it.
I'm pretty sure I should use hx-ws, but it is just completely unclear for me how.
chall-interface.html (here is a part which I want to update)
{% load static %}
{% load tagz %}
<div id='chall-interface' class="card-bottom mb-2">
<button onclick="call('challFollows',{'id':'{{chall.id}}'}, this)" class='icon icon-s rounded-sm float-end background-transparent mb-2 me-1 color-white'><i class="font-12 fa fa-heart {% followedChall user chall %}"></i></button>
<button href="#" data-menu="comment-section" class="icon icon-s rounded-sm float-end background-transparent mx-1 mb-2">
<i class="font-12 fa fa-comments color-white"></i>
</button>
{% if chall.dealine_is_over %}
<button href="#" data-menu="rules" class="icon icon-s rounded-sm float-end background-transparent mx-1 mb-2">
<i class="font-12 fa color-white {% changeJoinButton user chall %}""></i>
</button>
<!-- Here is a code I'm asking about -->
{% if user == userParticipationStatus.user %}
<a href="/addResponse/{{chall.id}}" class="icon icon-s rounded-sm float-end background-transparent mx-1 mb-2">
<i class="font-12 fa fa-plus-square color-white"></i>
</a>
{% else %}
{% endif %}
<!-- Here is a code I'm asking about -->
{% if chall.user == user %}
<button class="icon icon-s rounded-sm float-end background-transparent mx-1 mb-2">
<i class="font-12 fa fa-pen color-white"></i>
</button>
{% else %}
{% endif %}
{% else %}
{% endif %}
<div class="card-bottom mb-1 w-25">
{% if chall.profile.id == None %}
{% elif chall.user == user %}
{% else %}
{% endif %}
<span class="float-start mx-3"><i>{{chall.profile.nickname}}</i></span>
</div>
</div>
It is added as {% include "include/chall-interface.html" %} in main html file from which a pop-up is activated
Here is a pop-up
{% load tagz %}
<div id="rules" class="menu menu-box-modal rounded-m" data-menu-width="350">
<div class="card card-style" style="margin: 0px !important">
<div class="content">
<strong class="font-12 mx-1">Rules</strong>
<span class="color-theme font-14 d-block mx-1">{{chall.rules}}</span>
<!-- This is the button -->
<button onclick="call('challParticipates',{'id':'{{chall.id}}'}, this)" class="close-menu btn btn-m float-end rounded-xl shadow-xl text-uppercase font-800 bg-highlight mx-1 my-2"><i>{% changeJoinButton2 user chall %}</i></button>
<!-- This is the button -->
<button data-bs-dismiss="modal" class="close-menu btn btn-m float-end rounded-xl shadow-xl text-uppercase font-800 bg-highlight mx-1 my-2"><i>Exit</i></button>
</div>
</div>
</div>
Here is a call function activated by the button:
function call(url, info, element) {
eventStatus = false
fetch("/"+url+"/", {
method: 'POST',
headers: {'X-CSRFToken': getCookie('csrftoken')},
body: JSON.stringify(info)
}).then(response => response.text())
.then(responseData => {
dataParsed = JSON.parse(responseData);
console.log(dataParsed)
if (dataParsed.eventStatus) {
element.firstElementChild.classList.add("color-gold");
element.firstElementChild.classList.remove("color-white");
}
else {
element.firstElementChild.classList.remove("color-gold");
element.firstElementChild.classList.add("color-white");
}
})
.catch(err => {
// if any error occured, then catch it here
console.error(err);
});
}
View.py
class ChallView(LoginRequiredMixin, TemplateView):
login_url = '/chalth/login'
redirect_field_name = ''
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
chall = Chall.objects.get(id=kwargs.get("id"))
context['chall'] = chall
currentUser = self.request.user
context['userParticipationStatus'] = Participates.objects.filter(user = currentUser, chall = chall).first()
return context
#login_required(login_url = '/chalth/login')
def ChallParticipatesView(request):
data = json.loads(request.body)
id = data.get("id", False)
if id:
challParticipate = Participates.objects.filter(chall_id=id, user=request.user).first()
eventStatus = False
if challParticipate:
challParticipate.delete()
eventStatus = False
else:
challParticipate=Participates()
chall = Chall.objects.get(id=id)
eventStatus = True
if chall:
challParticipate.chall = chall
challParticipate.user = request.user
challParticipate.save()
else:
return HttpResponse(status = 400)
else:
return HttpResponse(status = 400)
return HttpResponse(json.dumps({"eventStatus": eventStatus, "id": id}), status = 200)
As far as I can understand from your code, I can't see htmx in action.
I suggest you first try using the inline way, for example:
<button hx-post="/clicked"
hx-trigger="click"
hx-target="#parent-div"
hx-swap="outerHTML"
>
Click Me!
</button>
to see if your problem is about:
the server that doesn't return valid HTML
the server that returns an error (that will stop the swap)
the wrong usage of htmx APIs
Also make sure to know what the properties:
hx-trigger
hx-target
hx-swap
do.
I hope I have helped 😊
I have my for loop in Django such as its only opening the modal for the first element and nothing happens for other elements.
This is my HTML file it display all elements in a table with delete button. When clicking delete button a modal is opened but it is opened for the first element only, what should I change in this?
<table>
{% for card in cards %}
<tr class="record">
<td>{{card.number}}</td>
<td>
<button
class="hover:bg-gray-500 duration-500"
id="delete-btn"
>
</button>
<div
class="
fixed
flex
justify-center
items-center
hidden
"
aria-labelledby="modal-title"
aria-modal="true"
id="overlay"
>
............. #some lines of code
<div
class="
bg-gray-50
px-4
py-3
sm:px-6 sm:flex sm:flex-row-reverse
"
>
<a
href="{% url 'p:delete-card' card.id %}"
id="delbutton"
>
<button
type="button"
class="
w-full
inline-flex
justify-center
"
>
Delete
</button>
</a>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
My js to open the modal on button click
window.addEventListener('DOMContentLoaded',() =>{
const overlay = document.querySelector('#overlay')
const delbtn = document.querySelector('#delete-btn')
const toggleModal = () => {
overlay.classList.toggle('hidden')
overlay.classList.add('flex')
}
delbtn.addEventListener('click',toggleModal)
})
I solved it like this with the help of Data in Django for loop {% for %} not loading for Modal
I changed the id of all the buttons like this and added delete-button class!
<button class="hover:bg-gray-500 duration-500 delete-button" id="delete-btn_{{card.id}}">
</button>
Like this added card.id in overlay too.
My Jquery:
$(".delete-button").click(function() {
var id = $(this).attr("id").split("_")[1]
$(`#overlay_${id}`).show();
});
Every modal should have a different id in the for loop.
You can use something like id="modal{{card.id}}"
Then select that id
Does that help you?
I have a django function based view, inside it a I have a checklist of checkmarks and some text, when I tap one I want the database to update, how do I accomplish this?
Note that I don't have made any efforts yet to change the value and I hope someone here can help me with that!
#login_required
def detailStudyplanPage(request,pk):
username = request.user
tks = Task.objects.filter(studyplan__id=pk)
object = get_object_or_404(Studyplan,pk=pk)
return render(request, 'detailStudyplan.html',{'object':object, 'MyName': username, 'tasks': tks})
class Checker(models.Model):
name = models.CharField(max_length=100)
checked = models.BooleanField(default=False)
sender = models.ForeignKey(UserProfile, blank=True, on_delete=models.CASCADE, related_name="person_who_checks_checker")
canview = models.ManyToManyField(UserProfile, blank=True, related_name="can_view_checker")
<div>
<div class="progress">
<div class="progress-bar bg-success" style="width:42%;"></div>
</div>
<div class="d-flex justify-content-between text-small">
<div class="d-flex align-items-center">
<i class="material-icons">playlist_add_check</i>
<span>3/7</span>
</div>
<span>Ska vara färdig {{task.deadline}}</span>
</div>
</div>
{% for checker in Checkers %}
<div class="row">
<div class="form-group col">
<span class="checklist-reorder">
<i class="material-icons">reorder</i>
</span>
<form method="post" action="{% url checker_check checker.id %}"></form>
<input type="checkbox"
{% if checker.checked == True %}
checked
{% endif %}
>
<style>
.checkerName {
margin-left: 10px
}
</style>
<h class='checkerName'>{{ checker.name }}</h>
</div>
<!--end of form group-->
</div>
{% endfor %}
You create two new views with URLs like: /checker/{id}/check and /checker/{id}/uncheck and based on the tap you do a POST to the correct URL.
The URL is linked up to a view that retrieves the check object, changes its boolean property and saves it.
In the view:
checker = Checker.objects.get(pk=pk)
checker.checked = True
checker.save()