plotly django bar doesn't show chart - django

if i print df_costo the result of the dataframe is ok, but in html file doesn0t show nothing
''' code '''
def fase_progetto(request):
try:
qs_costo = CostoFase.objects.all()
costo_fase_data =[
{
'Responsabile': x.responsabile,
'Costo': x.costo
} for x in qs_costo
]
df_costo = pd.DataFrame(costo_fase_data)
print(df_costo)
fig_costo = px.bar(df_costo, x="Responsabile", y="Costo")
gantt_plot_costo = plot(fig_costo, output_type="div")
context = {'costo_plot_div': gantt_plot_costo, 'form': form}
return render(request, 'progetti/progetti.html', context)
except:
return render(request, 'progetti/progetti.html', {'form': form})

Related

How I can reduce logic of hande form in next Django view?

I'm studing a django course right now. Teacher showed how find short route with ascross points by graph algorithm. He writed many code in view, I think it's some dirty. I shorten piece of code by using session in RouteSession class. But there is still many code.
Should do any thing in this case? Thanks.
def find_routes(request):
if request.method == "POST":
form = RouteForm(request.POST or None)
if form.is_valid():
data = form.cleaned_data
from_city = data['from_city']
to_city = data['to_city']
across_cities_form = data['across_cities']
travel_time = data['travel_time']
graph = get_graph()
all_ways = list(dfs_paths(graph, from_city.id, to_city.id))
if len(all_ways) == 0:
messages.error(request, 'There is no routes')
return render(request, 'routes/home.html', {'form': form})
if across_cities_form:
across_cities = [city.id for city in across_cities_form]
right_ways = []
for way in all_ways:
if all(point in way for point in across_cities):
right_ways.append(way)
if not right_ways:
messages.error(request, 'The route through these cities is impossible')
return render(request, 'routes/home.html', {'form': form})
else:
right_ways = all_ways
trains = []
for route in right_ways:
tmp = {'trains': []}
total_time = 0
for i in range(len(route) - 1):
qs = Train.objects.filter(from_city=route[i], to_city=route[i + 1])
qs = qs.order_by('travel_time').first()
total_time += qs.travel_time
tmp['trains'].append(qs)
tmp['total_time'] = total_time
if total_time <= int(travel_time):
tmp['from_city'] = from_city
tmp['to_city'] = to_city
trains.append(tmp)
if not trains:
messages.error(request, 'Travel time is longer than you're looking for')
return render(request, 'routes/home.html', {'form': form})
trains = sorted(trains, key=lambda x: x['total_time'])
routes = SessionRoute(request)
routes.clear()
routes.add(trains)
cities = {'from_city': from_city.name, 'to_city': to_city.name}
context = {'form': RouteForm(), 'routes': routes, 'cities': cities}
return render(request, 'routes/home.html', context)
return render(request, 'routes/home.html', {'form': form})
else:
messages.error(request, 'Please create a route')
form = RouteForm()
return render(request, 'routes/home.html', {'form': form})
Thanks for comment.
I moved logic to form class, and reloaded clean() method:
def clean(self, *args, **kwargs):
from_city = self.cleaned_data.get('from_city')
to_city = self.cleaned_data.get('to_city')
across_cities_data = self.cleaned_data.get('across_cities')
travel_time = self.cleaned_data.get('travel_time')
graph = get_graph()
all_ways = list(dfs_paths(graph, from_city.id, to_city.id))
if len(all_ways) == 0:
raise forms.ValidationError('Маршрута, удовлетворяющего условиям не существует.')
if across_cities_data:
across_cities = [city.id for city in across_cities_data]
right_ways = []
for way in all_ways:
if all(point in way for point in across_cities):
right_ways.append(way)
if not right_ways:
raise forms.ValidationError('Маршрут через эти города невозможен')
else:
right_ways = all_ways
trains = []
for route in right_ways:
tmp = {'trains': []}
total_time = 0
for i in range(len(route) - 1):
qs = Train.objects.filter(from_city=route[i], to_city=route[i + 1])
qs = qs.order_by('travel_time').first()
total_time += qs.travel_time
tmp['trains'].append(qs)
tmp['total_time'] = total_time
if total_time <= int(travel_time):
tmp['from_city'] = from_city
tmp['to_city'] = to_city
trains.append(tmp)
if not trains:
raise forms.ValidationError('Время в пути больше заданного')
self.cleaned_data['trains'] = trains
return super(RouteForm, self).clean()
It works great!

Edit an object based on an attribute's value in Django

I have a view called Edit, that edits an object. I want the user to only be able to edit it if it's unlocked, meaning, an attribute is called locked = BooleanField() and in the view, you first check whether the object is locked or not before proceeding.
This is the edit function so far:
#login_required
def editdossier(request, pk):
dossier = get_object_or_404(Dossier, id=pk)
form = AddDossierForm(request.POST or None, instance = dossier)
context = {'form': form}
if form.is_valid():
dossier = form.save(commit= False)
dossier.save()
context = {
'form': form,
'dossiers': Dossier.objects.all()
}
return render(request, 'dashboard/home.html', context)
else:
context= {'form': form}
return render(request,'dashboard/modifier_dossier.html' , context)
And this is what I want to do:
#login_required
def editdossier(request, pk):
dossier = get_object_or_404(Dossier, id=pk)
# CHECK IF DOSSIER.LOCKED == FALSE:
form = AddDossierForm(request.POST or None, instance = dossier)
context = {'form': form}
if form.is_valid():
dossier = form.save(commit= False)
dossier.save()
context = {
'form': form,
'dossiers': Dossier.objects.all()
}
return render(request, 'dashboard/home.html', context)
else:
context= {'form': form}
return render(request,'dashboard/modifier_dossier.html' , context)
I did the following check:
if dossier.locked == false:
proceed
but the condition is not checked. I tried if dossier[0].locked == false but it shows an error saying the object is not indexable.

django - Upload page must only be accessible once the form is submitted. Directly entering the upload url should not work

Uploading a file is only allowed once the form is submitted. The upload url must not be accessible otherwise.
After the user logs in, the upload url is directly accessed. How can i restrict this? This will create multiple entries of file upload for the same form
models.py
class uploadmeta(models.Model):
path = models.ForeignKey(Mdform, verbose_name="ID", on_delete=models.PROTECT)
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
datafile = models.FileField(upload_to=get_upload_folder, verbose_name="Dataset", validators=[validate_file_extension])
def get_absolute_url(self):
return reverse('file_list', kwargs={'pk': self.pk})
views.py
if request.user.is_authenticated:
if request.method == 'POST':
form = uploadmetaform(request.POST, request.FILES)
if form.is_valid():
path = form.cleaned_data['path']
if uploadmeta.objects.filter(path=path).exists():
user = form.cleaned_data['user']
datafile = form.cleaned_data['datafile']
context = {
'path': path,
'user': user,
'datafile': datafile
}
template = loader.get_template('nameexists.html')
return HttpResponse(template.render(context, request))
else:
user = form.cleaned_data['user']
datafile = form.cleaned_data['datafile']
path = dict(form.fields['path'].path)[path]
print(path)
b = form(path=path, user=user, datafile=datafile)
b.save()
context = {
'path': path,
'user': user,
'datafile': datafile
}
template = loader.get_template('thankyou.html')
return HttpResponse(template.render(context, request))
else:
form = uploadmetaform()
return render(request, 'uploaddata.html', {'form': form})
else:
return render(request, 'home.html')```
from django.shortcuts import render
from basicform.forms import BasicForm
from django.template import loader
from django.http import HttpResponse
from basicform.choices import *
from basicform.models import BasicFormModel
def responseform(request):
if request.method == 'POST':
basicForm = BasicForm(request.POST)
if basicForm.is_valid():
name = basicForm.cleaned_data['name']
if BasicFormModel.objects.filter(name=name).exists():
favourite_color = basicForm.cleaned_data['favourite_color']
choices = basicForm.cleaned_data['choices']
context = {
'name': name,
'favourite_color': favourite_color,
'choices': choices
}
template = loader.get_template('nameexists.html')
return HttpResponse(template.render(context, request))
else:
favourite_color = basicForm.cleaned_data['favourite_color']
choices = basicForm.cleaned_data['choices']
print("cleanded choices="+choices)
choices = dict(basicForm.fields['choices'].choices)[choices]
print(choices)
b = BasicFormModel(name=name, favourite_color=favourite_color, choices=choices)
b.save()
context = {
'name': name,
'favourite_color': favourite_color,
'choices': choices
}
template = loader.get_template('thankyou.html')
return HttpResponse(template.render(context, request))
else:
form = BasicForm()
return render(request, 'responseform.html', {'form':form});

fetch id from url in class in django

I want to fetch id from url so that i can use the queryset in diff. mehtods of class. but it is showing:
schedule = get_object_or_404(Schedule, id=kwargs['pk'])
NameError: name 'kwargs' is not defined
Here's My Code:
class SubmitAttendanceView(View):
template_name = 'schedule/submit_attendance.html' # this html file will be included in 'schedule/scheduledetail.html'
form_class = AttendanceForm
schedule = get_object_or_404(Schedule, id=kwargs['pk'])
students = Student.objects.filter(course__id__in=schedule.course.all(), sem=schedule.sem, subject__id__contains=schedule.subject.id).order_by('roll_no')
def get(self, request, pk):
form = self.form_class()
return render(request, self.template_name, {'form': form, 'students': self.students})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
date = form.cleaned_data['lecture_date']
lecture = self.schedule.id
subject = self.schedule.subject.id
x = 1 # a counter to fetch each checkbox from template by their name
for student in self.students:
course = Course.objects.get(id=student.course.id)
mark = self.request.POST[f'mark{x}']
if not mark:
mark = 0
attendance = Attendance(lecture=lecture, subject=subject, course=course, student=student, lecture_date=date, mark=mark)
attendance.save()
x += 1
return redirect('schedule')
return render(request, self.template_name, {'form': form, 'students': students})
urls.py:
path('<int:pk>/submit/', SubmitAttendanceView.as_view(), name='submit-attendance')
in template:
<a class="btn btn-md btn-danger add-new my-2" type="button" href="{% url 'submit-attendance' schedule.pk %}">Submit Attendance</a>
also tell if there's another way in which i can pass the queryset to variable and use it in my class methods
Solved:
class SubmitAttendanceView(View):
template_name = 'schedule/submit_attendance.html' # this html file will be included in 'schedule/scheduledetail.html'
form_class = AttendanceForm
def get_schedule(self, value):
return get_object_or_404(Schedule, id=value)
def get_students(self, value):
schedule = self.get_schedule(value)
# specify Students queryset
students_queryset = Student.objects.filter(course__id__in=schedule.course.all(), sem=schedule.sem, subject__id__contains=schedule.subject.id).order_by('roll_no')
return students_queryset
def get(self, request, **kwargs):
form = self.form_class()
students = self.get_students(kwargs['pk'])
return render(request, self.template_name, {'form': form, 'students': students})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
date = form.cleaned_data['lecture_date']
schedule = self.get_schedule(kwargs['pk'])
lecture = Schedule.objects.get(id=schedule.id)
subject = Subject.objects.get(id=schedule.subject.id)
x = 1 # a counter to fetch each checkbox from template by their name
students = self.get_students(kwargs['pk'])
for student in students:
course = Course.objects.get(id=student.course.id)
mark = self.request.POST.get(f'mark{x}')
if not mark:
mark = 0
attendance = Attendance(lecture=lecture, subject=subject, course=course, student=student, lecture_date=date, mark=mark)
attendance.save()
x += 1
return redirect('schedule')
return render(request, self.template_name, {'form': form, 'students': students})
After Doing Above Changes in Code , It is Working Fine
You can't use kwargs in class attribute, becaue it's keyword argument that were passed to your view. You can use it in the view only.
class SubmitAttendanceView(View):
template_name = 'schedule/submit_attendance.html' # this html file will be included in 'schedule/scheduledetail.html'
form_class = AttendanceForm
def get_schedule(self, **kwargs):
return get_object_or_404(Schedule, id=kwargs['pk'])
def get_students(self, **kwargs):
schedule = self.get_schedule(kwargs)
# specify Students queryset
students_queryset = Student.objects.filter(...)
return students_queryset
def get(self, request, **kwargs):
form = self.form_class()
students = self.get_students(kwargs)
return render(request, self.template_name, {'form': form, 'students': students})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
date = form.cleaned_data['lecture_date']
schedule = self.get_schedule(kwargs)
lecture = schedule.id
subject = schedule.subject.id
x = 1 # a counter to fetch each checkbox from template by their name
students = self.get_students(kwargs)
for student in self.students:
course = Course.objects.get(id=student.course.id)
mark = self.request.POST[f'mark{x}']
if not mark:
mark = 0
attendance = Attendance(lecture=lecture, subject=subject, course=course, student=student, lecture_date=date, mark=mark)
attendance.save()
x += 1
return redirect('schedule')
return render(request, self.template_name, {'form': form, 'students': students})

This is returning error. (django 1.5)

**
This is the ValueError it is returning. The view
poster.views.post_tweet didn't return an HttpResponse object
**
poster/views.py
from django.http import HttpResponseRedirect
def post_tweet(request, tweet_id=None):
tweet = None
if tweet_id:
tweet = get_object_or_404(Tweet, id=tweet_id)
if request.method == 'POST':
form = TweetForm(request.POST, instance=tweet)
if form.is_valid():
new_tweet = form.save(commit=False)
new_tweet.state = 'pending'
new_tweet.save()
send_review_email(tweet)
return HttpResponseRedirect('/post/thankyou/')
else:
form = TweetForm(instance=tweet)
return render(request,'post_tweet.html',{'form': form})
def thank_you(request):
tweets_in_queue = Tweet.objects.filter(
state='pending').aggregate(Count('id')).values()[0]
return render(request, 'thank_you.html',
{'tweets_in_queue': tweets_in_queue})
myproject/urls.py
url(r'^post/', include('poster.urls'))
poster/urls.py
url(r'^thankyou', 'thank_you'),
If it's a POST, but the form isn't valid, you're not returning anything. If you move the return render(request,'post_tweet.html',{'form': form}) left by one indentation level it should all work.