Putting a click event for a dialogue box with Django Tables2 - python

I am trying to make a click event with Django Tables2 so that whenever someone clicks on a delete link in a row it will create a dialogue box for confirmation before deleting the row. Here is my code:
models.py
class Schedules(models.Model):
course_name = models.CharField(max_length=128, choices=COURSE_NAME_CHOICES, default='a-plus')
location = models.CharField(max_length=128, choices=LOCATION_CHOICES, default='south_plainfield')
room = models.CharField(max_length=128, choices=ROOM_CHOICES, default='A')
start_date = models.DateField(auto_now=False, auto_now_add=False, default=datetime.date.today)
start_time = models.CharField(max_length=128, choices=START_TIME_CHOICES, default='eight-thirty am')
end_time = models.CharField(max_length=128, choices=END_TIME_CHOICES, default='eight-thirty am')
instructor = models.CharField(max_length=128, choices=INSTRUCTOR_CHOICES, default='adewale')
total_hours = models.CharField(max_length=128, choices=TOTAL_HOURS_CHOICES, default='six')
hours_per_class = models.CharField(max_length=128, choices=HOURS_PER_CLASS_CHOICES, default='four_and_half')
frequency = models.CharField(max_length=128)
status = models.CharField(max_length=128, choices=STATUS_CHOICES)
interval = models.CharField(max_length=128, choices=INTERVAL_CHOICES, default='1 day')
initiated_by = models.CharField(max_length=128, null=True)
schedule_id = models.IntegerField(default=0)
tables.py
class ScheduleListTable(tables.Table):
change = tables.TemplateColumn('Update / Cancel / Event / '
'<a href="/schedule/delete_schedule/{{ record.id }}"
onclick="return confirm("Are you sure you want to delete this?")">Delete</a>',
verbose_name=u'Change', )
class Meta:
model = Schedules
fields = ('id', 'course_name', 'start_date', 'start_time', 'hours_per_class', 'instructor', 'change',)
attrs = {"class": "paleblue"}
views.py
def schedule_List(request):
context_dict = {}
schedule_list = Schedules.objects.order_by('start_date')
table = ScheduleListTable(schedule_list)
context_dict['table'] = table
return render(request, "schedule/schedule_list.html", context_dict)
schedule_list.html
<div id="schedule_list_table">
{% if table %}
{% render_table table %}
{% endif %}
</div>
For some reason, I can't make the onclick event that makes the confirmation dialogue box appear, and it just goes straight to deleting. I assume that it's written incorrectly in tables.py, but I don't know how to write it correctly in that case. Or do I need to do something else?

Have a look at the rendered html, for example using your browsers inspect context menu option. I think you could see there that there is a problem with the double quotes you use.
The onclick-attribute is enclosed by double quotes, but the message passed as argument to confirm() is also enclosed by double quotes. This results in your browser interpreting the attribute as `onclick="return confirm(" and ignores the gibberish it cannot understand which is your message.
You can fix that by using single quotes to enclose the message argument to confirm(), either by escaping them in the syntax you used (\'), or by using triple quotes like this:
template_code = '''
Update / Cancel / Event /
<a href="/schedule/delete_schedule/{{ record.id }}"
onclick="return confirm('Are you sure you want to delete this?')">Delete</a>'''

Related

An Unexpected Error while trying to delete data

I am doing CRUD using serializers and foreign key as tasked,the problem is that when I am trying to delete a data,an error which is completely unexpected has come.
this error should not be coming as I am not missing the id in the below functions and html code
NOTE : I am doing soft delete hence the parameter 'isactive' is there
delete function
def delete(request,id):
deleteclothes = Products.objects.all(id=id)
delclothes = {}
delclothes['isactive']=False
form = POLLSerializer(deleteclothes,data=delclothes)
if form.is_valid():
print("error of form when valid:",form.errors)
form.save()
return redirect('polls:show')
else:
print("error of form when not valid:",form.errors)
return redirect('polls:show')
html code of product_list
<td>
<a href="/delete/{{result.id}}/" onclick="return confirm('Are You Sure you want to delete?')">
<button class="btn btn-danger">
Delete
</button>
</a>
</td>
models
class Products(models.Model):
categories = models.ForeignKey(Categories,on_delete=models.CASCADE)
sub_categories = models.ForeignKey(SUBCategories,on_delete=models.CASCADE)
color = models.ForeignKey(Colors,on_delete=models.CASCADE)
size = models.ForeignKey(Size,on_delete=models.CASCADE)
# image = models.ImageField(upload_to = 'media/',width_field=None,height_field=None,null=True)
title = models.CharField(max_length=50)
price = models.CharField(max_length=10)
sku_number = models.CharField(max_length=10)
product_details = models.CharField(max_length=300)
quantity = models.IntegerField(default=0)
isactive = models.BooleanField(default=True)
where am I going wrong in the code?
You can't do deleteclothes = Products.objects.all(id=id), whether you retrieve all Products by doing :
deleteclothes = Products.objects.all()
Or you retrieve the one with the id you want (which is what you need here) with :
deleteclothes = Products.objects.get(id=id)

Django Passing Through List Items

I have a todo website that allows users to put a remind in a certain list, such as work, school, groceries, etc. However, I'm a bit lost on how to get the list name and their items to display.
Models.py:
class RemindList(models.Model):
parent_user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
title = models.CharField(max_length=50)
class Reminder(models.Model):
remind_types = [('Regular', 'Regular'), ('Long Term', 'Long Term')]
title = models.CharField(max_length=100)
description = models.TextField()
remind_time = models.DateTimeField(blank=True)
parent_user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
parent_list = models.ForeignKey(RemindList, on_delete=models.CASCADE, null=True)
type_of_remind = models.CharField(max_length=12, choices=remind_types, default='Regular')
complete = models.BooleanField(default=False)
Views.py:
#login_required(login_url='/login')
def home(request):
user = get_object_or_404(User, username=request.user.username)
context = {
'events': ToDoItem.objects.filter(parent_user=user),
'reminders': Reminder.objects.filter(parent_user=user, type_of_remind='Regular'),
'long_term_reminders': Reminder.objects.filter(parent_user=user, type_of_remind='Long Term'),
'remind_list_items': RemindList.objects.filter(parent_user=user),
}
return render(request, 'main/home.html', context)
I can pass through the list names, and I planned to just loop through them and add Reminder.objects.filter(parent_user=user, type_of_remind='Regular', parent_list=list_name) to context. However, theres no way to loop through them on the html side (can't do for loop because there are other context types), and you can't filter them on the html side (correct me if I'm wrong). Is there another way to do this?
Ok, it took me a few readings, but if what I understand is correct you want to be able to iterate over the ReminderList objects and also list out the Reminder items under each one.
My suggestion would be to add a method to ReminderList that returns the items in that list, you could then do something like this in your template
{% for list in reminder_lists %}
... List header stuff goes here ...
{% for item in list.get_reminder_items %}
... Print the item ...
{% endfor %}
{% endfor %}
(The Django templating language can be a little interesting in that object.identifier can map to either an attribute or an object method - this can be useful for cases like these).

Showing Many-To-Many in different model's form in Django?

Say I have three models, a Professor model, a Course model, and a Review model. The user is allowed to make a Review, which reviews a Professor that teaches a certain Course.
I'm thinking of how to model the many to many relationship of Professor and Course, and how to reference that relationship in Review. My idea so far is to use models.ManyToMany to link Professor and Course.
Models.py (Prof)
class Prof(models.Model):
first_name = models.CharField(max_length = 20, unique = False)
last_name = models.CharField(max_length = 20, unique = False)
def __str__ (self):
return self.first_name + " " + self.last_name
class Course(models.Model):
name = models.CharField(max_length = 20, unique = True)
prof = models.ManyToManyField(Prof)
def __str__ (self):
return self.name
Models.py (Review)
class Review(models.Model):
message = models.TextField(max_length = 4000)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(null = True)
rating = models.IntegerField(
default = 5,
validators = [MaxValueValidator(5), MinValueValidator(0)]
)
prof = models.ForeignKey(Prof, related_name = 'reviews')
course = models.ForeignKey(Course, related_name = 'reviews')
user = models.ForeignKey(User, related_name = 'reviews')
def __str__ (self):
return self.message
forms.py
class ReviewForm(ModelForm):
rating = CharField(widget=TextInput(attrs={'type': 'number','value': 5, 'min': 0, 'max': 5}))
class Meta:
model = Review
fields = ['message', 'rating', 'prof', 'course', 'user']
This is my code so far for displaying the form
<h1>New Review</h1>
<form method="POST">
{% csrf_token %}
<p>{{ review_form.message }}</p>
<p>{{ review_form.rating }}</p>
<p>{{ review_form.prof }}</p>
<!-- The prof chosen's courses should be shown here -->
<button type="submit">Save</button>
</form>
Right now, forms.py shows all the objects under Course, and i'm not sure how to instead show the courses of a professor. Is it possible to filter the form after a prof is chosen from the drop down, to display the courses he/she teacher?
It sounds like you're going about this the right way. You haven't mentioned your urls.py structure yet, or views.py but the most straightforward way to do this is to display the courses by professor, taking the professor's id (or slug-field) in as a parameter - either in the URL (v straightforward) or as the output from a form on a previous page (and reload the template with a professor parameter) or in Ajax, depending on your appetite for shiny-new-things.
In your view, when you call the form, you can then do, along the lines from this answer -
form.courses.queryset = Course.objects.filter(professor__in=[professor.id,])
Note that I've put filtered on a list here, which only has one item - it does give you scope to expand, or to use a queryset for more complicated functions later.
Tweak as appropriate if you're using class-based views. :)

Django trying to split and urlify tags in models, but code isn't working

I've got a setup where users can tag their posts, and then other uses can click on those tags to find more posts similar to those. I'm setting it up so that they can use more than one tag per post, split by commas. I can split the tags just fine in models.py, but I want to make them url safe as well and that doesn't seem to be happening.
Instead, it will show me the split words, but not with safe URLs.
This is my models.py:
def urlify(s):
# Remove all non-word characters (everything except numbers and letters)
s = re.sub(r"[^\w\s]", '', s)
# Replace all runs of whitespace with a single dash
s = re.sub(r"\s+", '-', s)
return s
class Post(models.Model):
created_by = models.ForeignKey(User, related_name='post_created_by')
pubdate = models.DateTimeField(default=timezone.now)
title = models.CharField(max_length=200, null=True, blank=True)
body = models.TextField(null=True, blank=True)
category = models.CharField(max_length=200, null=True, blank=True)
tags = models.CharField(max_length=200, null=True, blank=True)
last_updated = models.DateTimeField(default=timezone.now)
likes = models.ManyToManyField(User, related_name='post_likes')
def __unicode__(self):
return self.title
def split_tags(self):
alltags = self.tags.split(', ')
for tag in range(len(alltags)):
urlify(alltags[tag])
return alltags
in the template I'm returning this:
Tagged:
{% for tag in post.split_tags %}
{% if forloop.last %}
{{tag}}
{% else %}
{{tag}},
{% endif %}
{% endfor %}
Would it be better to run the urlify in the views instead of the models? It would be nice if I could display the tags as the user wrote them but keep them URL safe in the background.
In split_tags function you are only iterating alltags without saving result from urlify. You can do it in one line with list comprehension:
def split_tags(self):
return [urlify(tag) for tag in self.tags.split(', ')]
Your version need some changes:
def split_tags(self):
alltags = self.tags.split(', ')
result = []
for tag in alltags:
result.append(urlify(tag))
return result
Note that there is similar to your urlify function in django utils - slugify:
slugify()
Converts to lowercase, removes non-word characters
(alphanumerics and underscores) and converts spaces to hyphens. Also
strips leading and trailing whitespace.

Tried to get data from ManyToManyField

I tried to get data from ManyToManyField but found not luck. Will you please help me?
Here is My Song App Models.
class Artist(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique = True,max_length=100,help_text="Suggested value automatically generated from name. Must be unique.")
class Album(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique = True,max_length=100,help_text="Suggested value automatically generated from name. Must be unique.")
path = models.CharField(max_length=100,null=True, blank=True)
language = models.ForeignKey(Category)
albumid = models.CharField(max_length=100)
class Song(models.Model):
title = models.CharField(max_length=100)
artist = models.ManyToManyField(Artist)
music = models.ForeignKey(Music)
album = models.ForeignKey(Album)
Here is my view. I want to print Artist with titles. Titles are working fine. but not Artist
def movie_details(request,slug):
movies = get_object_or_404(Movie,slug=slug)
# calculating wikipedia directory structer for images
#image_name = movies.image
name = movies.title
album_name = Album.objects.get(name__exact=name)
album_id = album_name.id
song_list = Song.objects.filter(album=album_id)
#image_path = generateWikiImage(image_name)
#
return render_to_response('base_movies.html',locals(),
context_instance=RequestContext(request)
)
I tried in template like this. {{song_list.artist}} and getting message like this <django.db.models.fields.related.ManyRelatedManager object at 0x024CBED0>
thanks
ManyRelatedManager is the object that handles the ManyToMany relation there. To get the list of objects that you're looking for, you need to use its all() method.
In this case, you'd use {{song_list.artist.all}}, which will give you a QuerySet that you can then iterate over in your template.
ManyToManyField holds queryset, so you can't just output it in template. You should iterate over it.
Like this (song is some Song instance)
<ul>
{% for artist in song.artist.all %}
<li>{{ artist.name }}</li>
{% endfor %}
</ul>

Categories