I am using the rest frame in my django app in order to access some data.
For some reason, I do not manage to access it. I have no error message but the data is not showing up.
my views are.
class TeamChartData(APIView):
queryset = MyUser.objects.all()
serializer_class = MyUserSerializer, #ProjectSerializer
permission_classes = []
http_method_names = ['get',]
def get_serializer_class(self):
return self.serializer_class
def get(self, request, format=None, *args, **kwargs):
cohesiveness_score = get_team_cohesivenss_score(self)
data = {
"cohesiveness_score":cohesiveness_score[0],
}
return Response(data)
my Html :
{% extends 'base.html' %}
{% load static %}
{% block body %}
<div class="container paddingtop80 marginbottom30">
<div class="row">
{% if project.has_member_responses %}
<div class="col-8">
<div class="jumbotron greenback">
<h4>Welcome to the Project test "{{ project.name }}" Detail page</h4>
</div>
</div>
<div class="col-4">
<div class="jumbotron greenback">
<div class="inner-score">
<h6>Team Score</h6>
<h4>{{cohesiveness_score}}</h4>
</div>
</div>
</div>
{% else %}
<div class="col">
<div class="jumbotron greenback">
<h4>Welcome to the Project "{{ project.name }}" Detail page</h4>
</div>
</div>
{%endif%}
</div>
<!-- case 1 = if there is not team created or linked -->
{% if project.team_id == None %}
{% include "projectdetailtemp/noteamcreated.html" %}<
<!-- case 2 = if there is a team created but no team members -->
{% elif project.team_id and project.team_id.members.count == 0 %}
{% include "projectdetailtemp/teamnomember.html" %}<
<!-- any other situation -->
{% else %}
{% include "projectdetailtemp/other.html" %}
{% endif %}
{% if project.has_member_responses %}
{% include "survey/team_dashboard.html" %}
{% else %}
<div class="jumbotron redback">
We are still waiting for all members to answer the team questionnaire
</div>
{% endif %}
</div>
{% endblock%}
<script>
var endpoint = 'api/chart/data2'
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
console.log(data)
cohesiveness_score = data.cohesiveness_score
}
})
</script>
when I go to my endpoint I can see the data that I am trying to access to the problem does not come from the view.py I guess..
The data I am trying to access is :{{cohesiveness_score}}
Could someone help me ?
edited:
the view in question :
def TeamSelect(request):
#import pdb; pdb.set_trace()
if request.method == "POST":
select_form = EditSelectTeam(request.user, request.POST)
if select_form.is_valid():
data = select_form.cleaned_data['team_choice']
obj2 = Project.objects.filter(project_hr_admin=request.user)
obj3 = obj2.latest('id')
if obj3.team_id == None:
obj3.team_id = data
obj3.save()
obj4 = obj3.team_id
obj5 = obj4.members.all()
for i in obj5:
current_site = get_current_site(request)
message = render_to_string('acc_join_email.html', {
'user': i.first_name,
'domain':current_site.domain,
})
mail_subject = 'You have been invited to SoftScores.com please LogIn to get access to the app'
to_email = i.email
email = EmailMessage(mail_subject, message, to=[to_email])
email.send()
messages.success(request, 'test')
return HttpResponseRedirect(reverse('website:ProjectDetails', kwargs={'pk':obj3.id}))
else:
print('this project has already a team')
else:
print('Non Valid form')
else:
select_form = EditSelectTeam(request.user)
return render(request,'link_project.html',
{'select_form':select_form })
the url :
url(r'^project/(?P<pk1>[0-9]+)/linkteam2/$', views.TeamSelect, name='team_select'),
the link :
<span class="fa fa-link"></span> Link an existing team
By default rendering class of Views in Django rest is JSONRenderer. You need to define your rendering class to HTML and template name. After this, yiur data will be rendered in HTML.
from rest_framework.renderers import TemplateHTMLRenderer
class TeamChartData(APIView):
queryset = MyUser.objects.all()
serializer_class = MyUserSerializer, #ProjectSerializer
permission_classes = []
http_method_names = ['get',]
renderer_classes = [TemplateHTMLRenderer]
template_name = 'template_name.html'
Related
I'm using django parler to translate my models. now i'm creating a custom admin Panel and i have a view for create and update of Contents. I'm using a class based view inherit from "View" for both create and update views so i can't use the TranslatableCreateView and TranslatableUpdateView. I saw in the codes of Django parler that using TranslatableModelFormMixin you can add translation support to the class-based views. I used this mixin but still i don't have access to the language tabs.
Here is Views.py:
class ContentCreateUpdateView(TranslatableModelFormMixin, TemplateResponseMixin, View):
module = None
model = None
obj = None
template_name = 'content-form.html'
def get_model(self, model_name):
if model_name in ['text', 'video', 'image', 'file']:
return apps.get_model(app_label='courses', model_name=model_name)
return None
def get_form(self, model, *args, **kwargs):
Form = modelform_factory(model, exclude=['owner',
'order',
'created',
'updated'])
return Form(*args, **kwargs)
def dispatch(self, request, module_id, model_name, id=None):
self.module = get_object_or_404(Module, id=module_id, course__owner=request.user)
self.model = self.get_model(model_name)
if id:
self.obj = get_object_or_404(self.model,
id=id,
owner=request.user)
return super().dispatch(request, module_id, model_name, id)
def get(self, request, module_id, model_name, id=None):
form = self.get_form(self.model, instance=self.obj,)
return self.render_to_response({'form': form, 'object': self.obj})
def post(self, request, module_id, model_name, id=None):
form = self.get_form(self.model, instance=self.obj, data=request.POST, files=request.FILES)
if form.is_valid():
obj = form.save(commit=False)
obj.owner = request.user
obj.save()
if not id:
# new content
Content.objects.create(module=self.module, item=obj)
return redirect('module_content_list', self.module.id)
return self.render_to_response({'form': form, 'object': self.obj})
Template:
{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% load crispy_forms_filters %}
{% block content %}
<div class="col-md-12">
<!-- Horizontal Form -->
<div class="card card-primary">
<div class="card-header ">
{% if object %}
<h3 class="card-title mb-0 float-left"> Edit Content "{{ object.title }}"</h3>
{% else %}
<h3 class="card-title mb-0 float-left"> Add New Content</h3>
{% endif %}
</div>
<!-- /.card-header -->
<!-- form start -->
<div class="card-body">
<form method="post" enctype="multipart/form-data">
<div class="row">
<div class="col-12">
{% if language_tabs %}
<ul class="nav nav-tabs">
{% for url,name,code,status in language_tabs %}
{% if status == 'current' %}
<input type="hidden" class="language_button selected" name="{{ code }}"/>
<li class="nav-item">
<a class="current nav-link active"
aria-selected="true">{{ name }}</a>
</li>
{% else %}
<li class="nav-item">
<a class="{{ status }} nav-link"
href="{{ url }}"
aria-selected="false">{{ name }}</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
</div>
<div class="col-6">
{{ form }}
</div>
</div>
{% csrf_token %}
<div class="col-6">
<button class="btn btn-success">Save Content</button>
</div>
</form>
</div>
</div>
</div>
<!-- /.card -->
{% endblock %}
Here is the source code of django parler:
class TranslatableModelFormMixin(LanguageChoiceMixin):
"""
Mixin to add translation support to class based views.
For example, adding translation support to django-oscar::
from oscar.apps.dashboard.catalogue import views as oscar_views
from parler.views import TranslatableModelFormMixin
class ProductCreateUpdateView(TranslatableModelFormMixin, oscar_views.ProductCreateUpdateView):
pass
"""
def get_form_class(self):
"""
Return a ``TranslatableModelForm`` by default if no form_class is set.
"""
super_method = super().get_form_class
# no "__func__" on the class level function in python 3
default_method = getattr(
ModelFormMixin.get_form_class, "__func__", ModelFormMixin.get_form_class
)
if not (super_method.__func__ is default_method):
# Don't get in your way, if you've overwritten stuff.
return super_method()
else:
# Same logic as ModelFormMixin.get_form_class, but using the right form base class.
if self.form_class:
return self.form_class
else:
model = _get_view_model(self)
if self.fields:
fields = self.fields
return modelform_factory(model, form=TranslatableModelForm, fields=fields)
else:
return modelform_factory(model, form=TranslatableModelForm)
def get_form_kwargs(self):
"""
Pass the current language to the form.
"""
kwargs = super().get_form_kwargs()
# The TranslatableAdmin can set form.language_code, because the modeladmin always creates a fresh subclass.
# If that would be done here, the original globally defined form class would be updated.
kwargs["_current_language"] = self.get_form_language()
return kwargs
# Backwards compatibility
# Make sure overriding get_current_language() affects get_form_language() too.
def get_form_language(self):
return self.get_current_language()
The tabs should look like this:
But now it looks like this:
If someone have a similiar exprience, feel free to write your opinion
In the settings.py file find PARLER_LANGUAGES settings and change None to SITE_ID.
PARLER_LANGUAGES = {
1: (
{'code': 'en', }, # English
{'code': 'ru', }, # Russian
),
'default': {
'fallbacks': ['en'],
'hide_untranslated': False,
}
}
Am working on this app where users of the app can make payment to other users, but am currently challenge by the search functionality, since i can only search users on the app by their foreignKey only, but instead i would want to be able to search by users full name, email and username, when i search user by name i get this exception (Field 'id' expected a number but got 'Hong'. ). why does my query only limit me to search by user number(foreignKey).Here is my view to search user for payment.
class RequestSearchUser(LoginRequiredMixin, ListView):
model = FriendList
form_class = SearchUserForm
template_name = 'wallet/request_search_user_form.html'
def get_queryset(self):
try:
username = self.kwargs['search_user']
except:
username = ''
if username != '':
object_list = self.model.objects.filter(username=username)
else:
object_list = self.model.objects.all()
return object_list
def get_context_data(self, **kwargs):
context = super(RequestSearchUser, self).get_context_data(**kwargs)
query = self.request.GET.get("search_user")
context['user'] = self.request.user
if query:
queryset = (Q(user=query))
search_user = FriendList.objects.filter(queryset)
if not search_user:
messages.error(self.request, 'No user found.')
else:
search_user = []
context['search_user'] = search_user
context['nbar'] = 'request'
return context
Here is my search form.py
class SearchUserForm(forms.ModelForm):
class Meta:
model = User
fields = ('username',)
def clean_username(self):
username = self.cleaned_data['username'].strip()
return username
Here is the Html form
<div class="blog_details">
<h2>Request Money</h2><hr>
<form class="form-contact contact_form" action="{% url 'wallet:request' %}" method="get" novalidate="novalidate">
<div class="row">
<div class="col-12">
{% if messages %}
{% for message in messages %}
<div class="alert alert-danger" role="alert">
{{ message }}
</div>
{% endfor %}
{% endif %}
</div>
<div class="col-12">
{% for search_user in search_user %}
{% if search_user == request.user %}
<div class="alert alert-danger" role="alert">
Cannot input your username.
</div>
{% else %}
<meta http-equiv="refresh" content="0; url={% url 'wallet:request_money' search_user.id %}" />
{% endif %}
{% endfor %}
</div>
<div class="col-12">
<div class="form-group">
<input class="form-control" name="search_user" id="search_user" type="text" maxlength="45"
onfocus="this.placeholder = ''" onblur="this.placeholder = 'Username'" placeholder="Username" required/>
</div>
</div>
</div>
<div class="form-group mt-3">
<button type="submit" class="button button-contactForm boxed-btn">Search </button>
</div>
</form>
</div>
</article>
Error is here
object_list = self.model.objects.filter(user=username)
and here
queryset = (Q(user=query))
If you store username of user in field called username, you should filter by user__username
object_list = self.model.objects.filter(user__username=username)
queryset = (Q(user__username=query))
It's nicely described here Many-to-one
You can use contains so your query will look like this
if query:
queryset = (
Q(user__username__contains=query)|
Q(user__first_name__contains=query)|
Q(user__email__contains=query)
)
search_user = FriendList.objects.filter(queryset)
if not search_user:
messages.error(self.request, 'No user found.')
I have a template called courses for the url http://127.0.0.1:8000/gradebook/courses/. This template lists existing Course objects loads the CourseForm form. The form successfully creates new objects.
If I go to the addassessment template with url http://127.0.0.1:8000/gradebook/addassessment/7/, it correctly loads the AssessmentForm. I want to submit this form and then return to the previous courses template. The AssessmentForm submits and the object is saved, but when it redirects back to the courses template, the CourseForm does not load. The courses template loads, the expect html loads correctly other than the form fields. I notice that the url for this page is still http://127.0.0.1:8000/gradebook/addassessment/7/ and not ../gradebook/courses/.
app_name = 'gradebook'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('signup/', SignUpView.as_view(), name='signup'),
path('courses/', views.courses, name='courses'),
path('classroom/', views.classroom, name='classroom'),
path('objective/<int:course_id>/', views.addobjective, name='addobjective'),
path('addassessment/<int:course_id>/', views.addassessment, name='addassessment'),
]
#urls.py project
urlpatterns = [
path('', TemplateView.as_view(template_name='home.html'), name='home'),
path('admin/', admin.site.urls),
path('gradebook/', include('gradebook.urls')),
path('gradebook/', include('django.contrib.auth.urls')),
]
#models.py
class Course(models.Model):
course_name = models.CharField(max_length=10)
class Classroom(models.Model):
classroom_name = models.CharField(max_length=10)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
class Assessment(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
assessment_name = models.CharField(max_length=10)
objectives = models.ManyToManyField('Objective')
class Objective(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
objective_name = models.CharField(max_length=10)
objective_description = models.CharField(max_length=30)
#views.py
def courses(request):
course_list = Course.objects.order_by('course_name')
context = {'course_list': course_list}
if request.method == 'POST':
details = CourseForm(request.POST)
if details.is_valid():
course = details.save(commit=False)
course.save()
form = CourseForm(None)
context['form'] = form
return render(request, "gradebook/courses.html", context)
else:
context['form'] = details
return render(request, "gradebook/courses.html", context)
else:
form = CourseForm(None)
context['form'] = form
return render(request, "gradebook/courses.html", context)
def addassessment(request, course_id):
course_list = Course.objects.order_by('course_name')
this_course = Course.objects.get(id=course_id)
objectives = Objective.objects.filter(course=this_course).order_by('objective_name')
context = {'this_course': this_course}
context['objectives'] = objectives
context['course_list'] = course_list
if request.method == 'POST':
form = AssessmentForm(request.POST)
if form.is_valid():
assess = form.save(commit=False)
# save the course that the objective belongs to
assess.course = this_course
assess.save()
form.save_m2m()
return render(request, "gradebook/courses.html", context)
else:
context['form'] = form
return render(request, "gradebook/addassessment.html", context)
else:
form = AssessmentForm(None)
form.fields["objectives"].queryset = Objective.objects.filter(course=this_course)
context['form'] = form
return render(request, "gradebook/addassessment.html", context)
#forms.py
class AssessmentForm(ModelForm):
class Meta:
model = Assessment
fields = ('assessment_name', 'objectives',)
class CourseForm(ModelForm):
class Meta:
model = Course
fields = ["course_name"]
def clean(self):
super(CourseForm, self).clean()
course_name = self.cleaned_data.get('course_name')
if course_name and Course.objects.filter(course_name__iexact=course_name).exists():
self.add_error(
'course_name', 'A course with that course name already exists.')
if len(course_name) > 10:
self.add_error(
'Your course name cannot be longer than 10 characters')
return self.cleaned_data
#courses template: course.html
<div class="container">
<div class="row">
<div class="twelve columns">
<h1>Courses</h1>
</div>
</div>
<div class="row">
<div class="col-md-12">
{% if course_list %}
<ul>
{% for course in course_list %}
<li><div class = "row">
<div class = "col-md-3">
{{ course.course_name }}
</div>
</div></li>
{% endfor %}
</ul>
{% else %}
<p>No Courses are available.</p>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-3">
<p>Create a new course</p>
</div>
<div class="col-md-3">
<form action="{% url 'gradebook:courses' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<div class="form-group">
<button type="submit" class="btn btn-primary">
Submit
</button>
</div>
</form>
</div>
</div>
</div>
#addassessment template: addassessment.html
<div class="container">
<div class="row">
<div class="twelve columns">
<h1>{{ this_course }}</h1>
</div>
</div>
<div class="row">
<div class="col-md-3">
<p>Add an assessment to your class</p>
</div>
<div class="col-md-3">
<div class="form-group">
<form action="" method="post">
{% csrf_token %} {{ form|crispy }}
<div class="form-group">
<button type="submit" class="btn btn-secondary">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
There are no error messages.
When you submit your assessment form at http://127.0.0.1:8000/gradebook/addassessment/7/ your sending a post request back to your addassessment view function to process your form which you know. The url will still be the same as a result, which is what you are seeing.
I would suggest against returning the courses template if your assessment form is valid in the way you have written
#inside addassessment view function
return render(request, "gradebook/courses.html", context)
If you are just wanting to redirect to the courses view upon successfully saving the assessment form I suggest using the redirect shortcut.
# add to your import
from django.shortcuts import render, redirect
#inside addassessment view function - replacing "return render(request, "gradebook/courses.html", context)"
return redirect(courses)
This will send your request object to the courses view function. The redirect will use a GET action instead of a post so you'll just see what you would normally at http://127.0.0.1:8000/gradebook/courses/. This will also be the url!
I'm new to Python Django and I'm trying to set up a bound form with three fields where one field (which will be read only) takes an initial value and displays it on the form; the other two fields will be populated by the user when they completes the form. But when I try to submit the form, the form.is_valid returns false, and I'm not sure what I did wrong. Can anyone please help?
Thanks
Here's the code:
views.py
class AddKeyAccompView(TemplateView):
template_name = 'AddKeyAccomp.html'
def get(self, request, Program):
username = request.user.username
form = AddKeyAccompForm(request, Program=Program)
return render(request, self.template_name, {'form': form
,'title':'Add New Key Accomplishment'
,'User': username
})
def post(self, request, Program):
username = request.user.username
form = AddKeyAccompForm(request.POST, Program=Program)
if form.is_valid():
Name = form.cleaned_data['Name']
Description = form.cleaned_data['Description']
form.save()
form = AddKeyAccompForm(request, Program=Program)
return HttpResponseRedirect(reverse('ModInit', args=[Program]))
else:
return HttpResponse('invalid form')
args = {'form': form
,'title':'Add New Key Accomplishment'
,'User': username
,'Name': Name
,'Desc': Description
,'Program': Program
}
return render(request, self.template_name, args)
forms.py
class AddKeyAccompForm(forms.ModelForm):
def __init__(self, request, *args, **kwargs):
self.program = kwargs.pop('Program')
super(AddKeyAccompForm, self).__init__(*args, **kwargs)
self.fields['Program'].initial = self.program
class Meta:
model = Key_Accomplishments
fields = ('Name', 'Description', 'Program',)
widgets = {
'Name': forms.TextInput(attrs={'required':True, 'class':'form-control'})
,'Description': forms.Textarea(attrs={'required': True, 'class':'form-control'})
,'Program': forms.TextInput(attrs={'readonly':'readonly', 'class':'form-control'})
}
html file
{% extends 'base.html' %}
<!DOCTYPE html>
<html>
<head>
{% block head %}
<title>New Key Accomplishment</title>
{% endblock %}
</head>
<body>
{% block body %}
<div class="container">
<ol class="breadcrumb my-4">
<li class="breadcrumb-item active">
<center>{{ title }}</center>
</li>
</ol>
</div>
<br>
<div class="offset-3 col-md-6">
<form method="post">
{% csrf_token %}
<div class="form-group" style="padding-left:10%;">
{% for field in form %}
<label>{{ field.label_tag }}</label>
{{ field }}
<br>
{% endfor %}
</div>
<div class="btn" style="padding-left: 10%;">
<button type="submit">Submit</button>
</div>
</form>
</div>
{% endblock %}
</body>
</html>
I have a model with Usuario where the profile foto goes and it saves perfectly in the database, so to be able to add more images as if it were a gallery, I created another model called Gallery, I copied the same specificiation of what was already working in the model Usuario, however he is not saving the photos in the database, and I do not know where I am going wrong.
I appreciate any help.
and I need the Gallery model to receive the foreign Usuario key
Erro:
IntegrityError at /gallery-novo/
null value in column "usuario_id_id" violates not-null constraint
DETAIL: Failing row contains (3, IMG_20180622_101716179_BURST006.jpg, eu e meu amor, null).
views.py
def gallery(request):
gallery = Gallery.objects.all()
form = GalleryForm()
data = {'gallery': gallery, 'form': form}
return render(request, 'gallery.html', data)
def gallery_novo(request):
if request.method == 'POST':
form = GalleryForm(request.POST, request.FILES)
if form.is_valid():
form.save(user=request.user)
return redirect('sistema_perfil')
else:
form = GalleryForm
return render(request, 'gallery.html', {'form': form})
models.py
class Gallery(models.Model):
gallery = StdImageField( blank=False, variations={
'large': (600, 400),
'thumbnail': (100, 100, True),
'medium': (300, 200),
})
titulo = models.CharField(max_length=50, blank=False)
usuario_id = models.ForeignKey(User, on_delete=models.CASCADE, blank=False)
forms.py
class GalleryForm(forms.ModelForm):
gallery = forms.FileField(
widget=forms.ClearableFileInput(attrs={'multiple': 'True'}))
titulo = forms.CharField()
class Meta:
model = Gallery
fields = ( 'gallery', 'titulo')
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
return super(GalleryForm, self).__init__(*args, **kwargs)
def save(self, commit=True, user=None):
form = super(GalleryForm, self).save(commit=False)
form.usario_id = user
if commit:
form.save()
return form
gallery.html
{%extends 'bases/base.html' %}
{% load static %}
{% load bootstrap %}
{% load widget_tweaks %}
{% load crispy_forms_tags %}
{% block main %}
<div class="card text-white bg-primary">
<div class="card-header"><p class="card-text">
<small class="text-muted">
Home /
<a class="text-white">Cadastro</a>
</small></a></p> Cadastro de UsĂșario
</div>
<div class="card title ">
<div class="card-body text-secondary">
<form class="exampleone" action="{% url 'sistema_gallery_novo' %}" method="POST" enctype="multipart/form-data" id="form" name="form" validate >
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-4">
{{ form.gallery | as_crispy_field }}
</div>
<div class="form-group col-md-4">
{{ form.titulo | as_crispy_field }}
</div>
<div class="form-group col-md-4">
</div>
</div>
</div>
<button type="submit" class="btn btn-primary btn-block">Cadastrar</button>
</form>
</div>
</div>
</div>
{% endblock %}
{% block rightcol %}
{% include 'bases/rightcol.html' %}
{% endblock %}
{% block footer %}
{% include 'bases/footer.html' %}
{% endblock %}
urls.py
url(r'gallery/$', gallery, name='sistema_gallery'),
url(r'gallery-novo/$', gallery_novo, name='sistema_gallery_novo'),
In my opinion, you are reinventing the wheel, the django right approach is to use commit=False on save method:
def gallery_novo(request):
if request.method == 'POST':
form = GalleryForm(request.POST, request.FILES)
if form.is_valid():
my_novo_gallery = form.save(commit=False) #save no commit
my_novo_gallery.user=request.user #set user
my_novo_gallery.save() #save to db
return redirect('sistema_perfil')