Below is the user record present in MySQL Database table - auth_user
Please click the image if it is not clear here
Below is my code present in View.py file.
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.views import View
class loginController(View):
def get(self, request):
userobj = User.objects.filter(username = 'username')
return HttpResponse(request.POST.get('username'));
It returns just the username. Can you please suggest that why it just fetch the username and not the complete record?
Please let me know if you need more info
It returns the list of user objects represented by username. You can access all the properties of object as (obj.property). eg: if you have first_name in your user model
u = userobj.first()
u.first_name
u.last_name
If you want to fetch the complete user information, then you have to return User object, so that you can iterate throught that User object in your template
Example:-
Views.py
from django.views import generic
class loginController(generic.ListView):
template_name = 'project_app/user-list.html'
model = User
def get_queryset(self):
userlist = User.objects.all()
return userlist
project_app/user-list.html
{% if object_list %}
{% for user in object_list %}
<p>{{ user.username }}</p>
<p>{{ user.first_name }}</p>
{% endfor %}
{% endif %}
Related
I have a page for teachers to input the marks and registration number of the students..
After input, it gets stored in the database and the students can fill a form which asks for D.O.B and registration number and get's the marks based on that particular registration from the database..
But when I use post request for the students, it shows form is invalid and says that, the registration number already exists..
My views.py:
from django.shortcuts import render
from django.views.generic.list import ListView
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Mark
from django.contrib.auth.views import LoginView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import FormView
from .forms import ViewResultForm, AddResultForm
from django.contrib import messages
class ViewResultFormView(FormView):
template_name = 'main/home.html'
form_class = ViewResultForm
success_url= 'result'
def form_valid(self, form):
global registration_number
global dob
registration_number = form.cleaned_data['registration_number']
dob = form.cleaned_data['dob']
return super(ViewResultFormView, self).form_valid(form)
class MarkListView(ListView):
model = Mark
template_name = "main/result.html"
context_object_name = 'result'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['result'] = context['result'].get(registration_number=registration_number, dob=dob)
return context
class MarkCreateView(LoginRequiredMixin, CreateView):
model = Mark
template_name = "main/add.html"
form_class = AddResultForm
def form_valid(self, form):
total_10th = ((form.cleaned_data['class_10_sub_1'] + form.cleaned_data['class_10_sub_2'] + form.cleaned_data['class_10_sub_3'])/300)*30
total_11th = ((form.cleaned_data['class_11_English'] + form.cleaned_data['class_11_Maths'] +form.cleaned_data['class_11_Physics'] +form.cleaned_data['class_11_Chemistry'] +form.cleaned_data['class_11_Comp_Bio'])/500) * 30
total_12th = ((form.cleaned_data['class_12_English'] + form.cleaned_data['class_12_Physics'] +form.cleaned_data['class_12_Chemistry'] +form.cleaned_data['class_12_Maths']+ form.cleaned_data['class_12_Comp_Bio'] + form.cleaned_data['class_12_practicals_Physics'] + form.cleaned_data['class_12_practicals_Chemistry'] + form.cleaned_data['class_12_practicals_Comp_Bio'] )/500)*40
result = total_10th + total_11th + total_12th
total = form.save(commit=False)
total.teacher_name = self.request.user
total.result = result
total.save()
message = messages.success(self.request, f'Result added successfully')
return super().form_valid(form)
class CustomLoginView(LoginView):
template_name = 'main/login.html'
fields = '__all__'
redirect_authenticated_user = True
def get_success_url(self):
return reverse_lazy('add')
home.html:
{% extends 'main/base.html' %}
{%load crispy_forms_tags %}
{% block content %}
<div class="container mt-5 card shadow p-3 mb-5 bg-white rounded">
<legend>Enter your credentials</legend>
<form method="POST">
{% csrf_token %}
{{ form | crispy }}
<input class='btn btn-outline-info' type="submit" value="Submit">
</form>
</div>
{% endblock content %}
result.html:
{% extends 'main/base.html' %}
{% block content %}
<div class="container">
{{ result.student_name }}
<br>
{{ result.dob }}
<br>
{{ result.result }} %
</div>
{% endblock content %}
So once the teacher enters the marks of the student, I calculate the results and store it in the database.. But bcz the teacher has registered a particular registration number, it shows form is invalid when a student tries to enter the same registration number in the form.. I want the registration number to be unique..
So if I have to use GET in home.html, how to access the values of the form?
You should rewrite your ViewResultFormView.form_valid, because you do not want form.save() to be called in the super call. You should retrieve registration_number and dob from the form and then fill a context for the template with a results of the corresponding student.
Also I do not understand what are those global hacks for? If you need to store that info for a several site pages, then you should implement your own authentication for students which will store their auth tokens/cookies somewhere, and then use that authentication info to allow/deny access to certain pages.
If I have models like this:
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=255)
class Book(models.Model):
publisher = models.ForeignKey('Publisher')
title = models.CharField(max_length=255)
class BookImage(models.Model):
book = models.ForeignKey('Book')
file = models.ImageField(max_length=255)
title = models.CharField(max_length=255)
I want to make a page that:
Lists all the Books for a particular publisher (e.g. Book.objects.filter(publisher=34)).
For each Book, displays any existing BookImages.
For each Book displays 3 forms for uploading and titling new BookImages.
One submit button.
I don't need to edit the details of the Books - the forms are only for BookImages.
I'm getting in a tangle with modelformset_factory and inlineformset_factory and none of it is right... I feel like I'm making things too complicated. Any ideas?
Update:
Here are some things I've tried that head in a sort-of-right direction, but I'm not sure they help:
# Forms for multiple Books for this Publisher
# But I don't think I need forms for the Books in my situation?
my_publisher = Publisher.objects.get(pk=37)
BookFormSet = modelformset_factory(Book, fields=(['title']))
formset = BookFormSet(queryset=Book.objects.filter(publisher=my_publisher))
# Multiple BookImages on one Book:
# Good, but how do I do this for all of a Publisher's Books, and display existing BookImages?
my_book = Book.objects.get(pk=42)
BookImageFormSet = inlineformset_factory(Book, BookImage, fields=('file', 'title'))
formset = BookImageFormSet(instance=my_book)
I found an example of how to do this in this blog post. Below I've rewritten the example using my Publisher/Book/BookImage models, and generic class-based views, for future reference.
The form also allows the user to edit the titles of the Books, which wasn't what I originally wanted, but this seems easier than not doing it; the inline Book forms require at least one field each, so we may as well include the Book's title.
Also, to see how this worked, I've put together a small Django project using this code, and a little more detail, available on GitHub.
models.py:
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=255)
class Book(models.Model):
title = models.CharField(max_length=255)
publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE)
class BookImage(models.Model):
book = models.ForeignKey('Book', on_delete=models.CASCADE)
image = models.ImageField(max_length=255)
alt_text = models.CharField(max_length=255)
forms.py:
from django.forms.models import BaseInlineFormSet, inlineformset_factory
from .models import Publisher, Book, BookImage
# The formset for editing the BookImages that belong to a Book.
BookImageFormset = inlineformset_factory(
Book,
BookImage,
fields=('image', 'alt_text')),
extra=1)
class BaseBooksWithImagesFormset(BaseInlineFormSet):
"""
The base formset for editing Books belonging to a Publisher, and the
BookImages belonging to those Books.
"""
def add_fields(self, form, index):
super().add_fields(form, index)
# Save the formset for a Book's Images in a custom `nested` property.
form.nested = BookImageFormset(
instance=form.instance,
data=form.data if form.is_bound else None,
files=form.files if form.is_bound else None,
prefix='bookimage-%s-%s' % (
form.prefix,
BookImageFormset.get_default_prefix()),
)
def is_valid(self):
"Also validate the `nested` formsets."
result = super().is_valid()
if self.is_bound:
for form in self.forms:
if hasattr(form, 'nested'):
result = result and form.nested.is_valid()
return result
def save(self, commit=True):
"Also save the `nested` formsets."
result = super().save(commit=commit)
for form in self.forms:
if hasattr(form, 'nested'):
if not self._should_delete_form(form):
form.nested.save(commit=commit)
return result
# This is the formset for the Books belonging to a Publisher and the
# BookImages belonging to those Books.
PublisherBooksWithImagesFormset = inlineformset_factory(
Publisher,
Book,
formset=BaseBooksWithImagesFormset,
fields=('title',),
extra=1)
views.py:
from django.http import HttpResponseRedirect
from django.views.generic import FormView
from django.views.generic.detail import SingleObjectMixin
from .forms import PublisherBooksWithImagesFormset
from .models import Publisher, Book, BookImage
class PublisherUpdateView(SingleObjectMixin, FormView):
model = Publisher
success_url = 'publishers/updated/'
template_name = 'publisher_update.html'
def get(self, request, *args, **kwargs):
# The Publisher whose Books we're editing:
self.object = self.get_object(queryset=Publisher.objects.all())
return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
# The Publisher whose Books we're editing:
self.object = self.get_object(queryset=Publisher.objects.all())
return super().post(request, *args, **kwargs)
def get_form(self, form_class=None):
"Use our formset of formsets, and pass in the Publisher object."
return PublisherBooksWithImagesFormset(
**self.get_form_kwargs(), instance=self.object)
def form_valid(self, form):
form.save()
return HttpResponseRedirect(self.get_success_url())
templates/publisher_update.html:
{% extends 'base.html' %}
{% block content %}
<form action="" method="post" enctype="multipart/form-data">
{% for hidden_field in form.hidden_fields %}
{{ hidden_field.errors }}
{{ hidden_field }}
{% endfor %}
{% csrf_token %}
{{ form.management_form }}
{{ form.non_form_errors }}
{% for book_form in form.forms %}
{# Output a Book form. #}
{% for hidden_field in book_form.hidden_fields %}
{{ hidden_field.errors }}
{% endfor %}
<table>
{{ book_form.as_table }}
</table>
{# Check if our `nested` property exists, with BookImage forms in it. #}
{% if book_form.nested %}
{{ book_form.nested.management_form }}
{{ book_form.nested.non_form_errors }}
{% for bookimage_form in book_form.nested.forms %}
{# Output the BookImage forms for this Book. #}
{% for hidden_field in bookimage_form.hidden_fields %}
{{ hidden_field.errors }}
{% endfor %}
<table>
{{ bookimage_form.as_table }}
</table>
{% endfor %}
{% endif %}
{% endfor %}
<input type="submit" value="Update books">
</form>
{% endblock content %}
All formset_factory methods require a form which they can generate multiple times. So, you need to create a form (since you are using Models, you need to create a model form) for BookImage.
forms.py
class BookImageForm(ModelForm):
class Meta:
model = BookImage
# book field wont be generated in the template if it is excluded
exclude = ['book',]
views.py
from django.forms.formsets import formset_factory
def your_view(request):
# I'm just including the formset code which you need, im assuming you have the remaining code in working condition
# TO HANDLE NORMAL RENDERING OF FORM WHEN USER OPENS THE WEBPAGE
if request.method == "GET":
bookimage_form = BookImageForm()
bookimage_formset = formset_factory(bookimage_form, max_num=3)
return render(request, 'index.html', {'bookimage_formset': bookimage_formset})
# WHEN USER SUBMITS THE FORM
if request.method == "POST"
# Consider BookImageFormSet as a placeholder which will be able to contain the formset which will come through POST
BookImageFormSet = modelformset_factory(BookImage, BookImageForm, max_num=3)
# bookimage_formset is a variable which stores the Formset of the type BookImageFormSet which in turn is populated by the data received from POST
bookimage_formset = BookImageFormSet(request.POST)
# HIDDEN AUTO GENERATED FIELDS ARE CREATED WHEN THE FORMSET IS RENDERED IN A TEMPLATE, THE FOLLOWING VALIDATION CHECKS IF THE VALUE OF THE HIDDEN FIELDS ARE OKAY OR NOT
if bookimage_formset.is_valid():
# EACH FORM HAS TO BE INDIVIDUALLY VALIDATED, THIS IS NORMAL FORM VALIDATION. ONLY DIFFERENCE IS THAT THIS IS INSIDE A FOR LOOP
for bookimage_form in bookimage_formset:
if bookimage_form.is_valid:
bookimage_form.save()
return HttpResponse("Form saved!")
return HttpResponseRedirect('/')
PS: You can get the data from request.POST for other models in the same view to handle other data (such as the data for Books)
I have the following model with a m2m field where logged in Users can show interest in a publication:
models.py
from django.db import models
class Publication:
title = models.CharField(max_lenth=512)
users_interested = models.ManyToManyField(User)
views.py
from django.shortcuts import render
from django.views import View
from .models import Publication
class listPublicationView(View):
def get(self, request, *args, **kwargs):
publications = Publication.objects.all()
return render(request, "base.html", {'publications': publications})
Now i try to produce a "i am already interested" in the template when a logged in user is already interested in the publication:
base.html
{% for publication in publications %}
{{publication.title}}
{% if currently logged in User is interested in publication (check users_interested) %}
i am already interested
{% endif %}
{% endfor %}
I think about something like this:
{% if user.id in publication.users_interested__id %}
Try like this:
{% if request.user in publication.users_interested.all %}
request.user property holds the current logged in user
Then you use the in operator with publications.users_interested.all() (Note that there are no parenthesis on .all() in template
This seems to look like a good solution:
models.py
from django.db import models
class Publication:
title = models.CharField(max_lenth=512)
#added a reverse accessor
users_interested = models.ManyToManyField(User, related_name='users_interested')
view.py
from django.shortcuts import render
from django.views import View
from .models import Publication
class listPublicationView(View):
def get(self, request, *args, **kwargs):
publications = Publication.objects.all()
# create a set of group IDs that this user is a part of
current_user = request.user
user_publication_set = set(current_user.users_interested.values_list('id', flat=True))
#pass set to template
return render(request, "base.html", {'publications': publications, 'user_publication_set': user_publication_set})
base.html
{% for publication in publications %}
{{publication.title}}
{% if publication.id in user_publication_set %}
i am already interested
{% endif %}
{% endfor %}
Found this solution in Django: check for value in ManyToMany field in template
I am trying to create a Django app that allows a user to select a file name from a drop down menu and upload the file. Regardless of what the user has named their file, I will receive that file saved as whatever they selected on the drop down plus the date. I cannot seem to get my drop downs to show. Hours of reading the documentation, multiple stack overflow posts, and trial and error have not helped. * Does anyone know how to get the user-selected drop down value from views.py to models.py to be inserted into the uploaded file's path? *
On another note, I am sure there are other issues with my code, being a Django newb, so please point them out if you see them.
models.py
from django.db import models
from datetime import datetime
import os
def update_filename(instance, filename):
path = "documents/"
format = '{0}_{1}.csv'.format(vc, datetime.today().strftime('%Y%m%d'))
#note that vc is defined in views.py but I am not sure how to transfer this to models.py
#*************************************************************
return os.path.join(path, format)
class Document(models.Model):
docfile = models.FileField(upload_to= update_filename) #/%Y/%m/%d')
#value_chains = (('coffee', 'coffee'),('tea', 'tea'),)
dropdown = models.CharField(max_length=20, choices=(('coffee', 'coffee'),('tea', 'tea'),))
forms.py
from django import forms
from .models import Document
def validate_file_extension(value):
if not value.name.endswith('.csv'):
raise forms.ValidationError("Only CSV file is accepted")
class DocumentForm(forms.ModelForm):
docfile = forms.FileField(label='Select a file', validators=[validate_file_extension])
value_chains = (('coffee', 'coffee'),('tea', 'tea'),)
dropdown = forms.ChoiceField(choices=value_chains, required=True)
class Meta:
model = Document
fields = ['dropdown']
views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.views.generic.edit import CreateView
from .models import Document
from .forms import DocumentForm
def list(request):
# Handle file upload
if request.method == 'POST':
#bind the data to the form
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
#**** vc is defined here ************************************
vc = form.cleaned_data['dropdown']
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('file_upload_app.views.list'))
# if a GET (or any other method) we'll create a blank form:
else:
form = DocumentForm() # A empty, unbound form. This is what we can expect to happen the first time we visit the URL.
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'file_upload_app/list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
list.html
<form action="{% url "list" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.dropdown }}
<p>
<h6>
Note: the uploaded file must be in
<b>.CSV</b>
format and contain a column labeled "A" which contains
<em>only</em>
numbers.
</h6>
</p>
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload"/></p>
</form>
<!-- List of uploaded documents -->
<p>
{% if documents %}
<div class="col-sm-12" align="center" >
<ul>
<p>Files on server:</p>
{% for document in documents %}
<li>{{ document.docfile.name }}</li>
{% endfor %}
</ul>
</div>
{% else %}
<div class="col-sm-12" align="center" >
<p>No documents.</p>
</div>
I recommend you use Djano's CreateView for your view. In your case you would have
Class UploadDocumentView(CreateView):
model = Document
When you click submit on your form, and you have the action pointing to the correct view, it will create a new Document with the fields you provided.
Your template should have this in it, the url should be the name you gave your url. I recommend against using "list" as your url because that is a special name in python and Django has it's own concept of ListView.
<form id="upload_document" method="POST" action="{% url 'document:upload' %}">
{{ form }}
<input class="btn btn-primary" id="upload_document_button" type="submit" value="Upload Document"/>
</form>
Sometimes seeing a working example is useful. The one below uses Django's UpdateView. The UpdateView will use the get_object method to determine which object in the database to modify. It knows what model to look at because it is set to model = UserProfile, and it knows what values to save because you set them in your form.
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,
primary_key=True)
company_identifier = models.CharField(max_length=5, blank=False)
employee_id = models.CharField(max_length=20, null=True, blank=False)
forms.py
def get_company_choices():
company_list = [('','-------')]
companies = models.Company.objects.values_list('id', 'name').order_by('name')
company_list = list(chain(company_list, companies))
return company_list
class EmployerForm(forms.ModelForm):
employee_id_confirm = forms.CharField(label="Confirm Employee ID", required=True)
company_identifier = forms.ChoiceField(choices=get_company_choices, label="Company")
class Meta:
model = models.UserProfile
fields = ('company_identifier', 'employee_id')
labels = {
'employee_id': "Employee ID",
}
views.py
#method_decorator(login_required, name='dispatch')
class EmploymentUpdate(SuccessMessageMixin, UpdateView):
model = UserProfile
template_name = 'employee/update_employment.html'
form_class = forms.EmployerForm
success_url = reverse_lazy('employee:home')
success_message = "Employment Updated."
def get_object(self):
return self.model.objects.get(pk=self.request.user.userprofile.pk)
I found the solution, denoted by the **** below:
models.py:
from django.db import models
from datetime import datetime
import os
value_chains = (
('coffee', 'coffee'),
('tea', 'tea'),
)
def update_filename(instance, filename):
path = "documents/"
#*************************************************************
#use instance to access the instance of Document's CharField function, which is defined below
format = '{0}_{1}.csv'.format(instance.dropdown, datetime.today().strftime('%Y%m%d'))
#*************************************************************
return os.path.join(path, format)
class Document(models.Model):
docfile = models.FileField(upload_to= update_filename)
dropdown = models.CharField(max_length=20, choices=value_chains)
class Meta:
permissions = (("access_file_upload_app", "Access file upload tool."),)
views.py:
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.conf import settings
from .models import Document
from .forms import DocumentForm
#login_required
def doc_upload_view(request):
if request.user.has_perm('file_upload_app.access_file_upload_app') and settings.VC_ENABLED == 'Y':
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
#********************************************************
# make sure to pass the dropdown value to the Document call:
newdoc = Document(docfile = request.FILES['docfile'], dropdown = form.cleaned_data['dropdown'])
#********************************************************
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('file_upload_app.views.doc_upload_view'))
else:
form = DocumentForm() # An empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'file_upload_app/doc_upload_view.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
else:
return redirect('/home/')
forms.py:
from django import forms
from .models import Document
def validate_file_extension(value):
if not value.name.endswith('.csv'):
raise forms.ValidationError("Only CSV file is accepted")
class DocumentForm(forms.ModelForm):
value_chains = (('coffee', 'coffee'),('tea', 'tea'),)
docfile = forms.FileField(label='Select a file', validators=[validate_file_extension])
dropdown = forms.ChoiceField(choices=value_chains, required=True )
class Meta:
model = Document
fields = ('dropdown',)
doc_upload_view.html:
<!-- Upload form. Note enctype attribute! -->
<form action="{% url "doc_upload_view" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.dropdown }}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload"/></p>
</form>
<!-- List of uploaded documents -->
<p class="top-space">
{% if documents %}
<div class="col-sm-12" align="center" >
<ul>
<p>Files on server:</p>
{% for document in documents %}
<li>{{ document.docfile.name }}</li>
{% endfor %}
</ul>
</div>
{% else %}
<div class="col-sm-12" align="center" >
<p>No documents.</p>
</div>
{% endif %}
</p>
I would like to display the list of entries where the user.username foreignKey is egal to session username. I want to display the specific data related to a session user only.
models.py:
from django.db import models
class User(models.Model):
username = models.CharField(max_length=10)
email = models.EmailField(verbose_name='e-mail')
date_signed = models.DateTimeField('date signed')
class ezMap(models.Model):
map_name = models.CharField(max_length=50, )
user = models.ForeignKey(User)
views.py:
from django.shortcuts import *
from ezmapping.models import *
def listEzMap(request):
#really not sure how to do it...
username = request.session['username']
user_list = ezMap.objects.get(map_name = username)
return render_to_response("map_list.html", {'user_list': user_list})
map_list.html template:
{% extends "base.html" %}
{% block content %}
<div class="list">
<h2> Map list </h2>
{% for object in user_list %}
<li>{{ object.map_name }}</li>
{% endfor %}
</div>
{% endblock %}
Thank you for your help with this!
views.py:
def listEzMap(request):
user_list = ezMap.objects.filter(user=request.user)
return render_to_response("map_list.html", {'user_list': user_list})
You can always access the logged in user from request as user = request.user, then use that user information to take decisions on user basis:
user = request.user
user_list = ezMap.objects.get(map_name = user.username)
You should check django authtication system as mentioned by dm03514 in comment.