get data based on primary key and display in html - django

I am trying to get data based on primary key and display for EDIT in html page. but i am getting 'QuerySet' object has no attribute '_meta' error.
I try to resolve it by looking at other posts but unable to do so.. hope somebody will help in problem.
my forms:
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = ('stuName','stuCity','stuPhone','stuNationality','stuCreatedt')
class CourseForm(forms.ModelForm):
class Meta:
model = Course
fields = ('courseId','courseName','enrolledStu','students','dept')
class DeptForm(forms.ModelForm):
class Meta:
model = Dept
fields = ('deptId','deptName')
Models.py
class Student(models.Model):
stuName = models.CharField(max_length=100)
stuCity = models.CharField(max_length=100)
stuPhone = models.IntegerField(max_length=10)
stuNationality = models.CharField(max_length=50)
stuCreatedt = models.DateTimeField(default=timezone.now)
def __str__(self):
return '%s %s %s' % (self.stuName,self.stuCity,self.stuNationality)
Class Dept :
class Dept(models.Model):
deptId = models.AutoField(primary_key=True)
deptName = models.CharField(max_length=100)
def __str__(self):
return '%s %s' % (self.deptId, self.deptName)
class Course
class Course(models.Model):
courseId = models.AutoField(primary_key=True)
courseName = models.CharField(max_length=100)
enrolledStu = models.IntegerField(max_length=3)
students = models.ManyToManyField(Student)
dept = models.ForeignKey(Dept, on_delete=models.CASCADE)
def __str__(self):
return '%s %s %s %s' % (self.courseName,self.enrolledStu,self.students,self.dept)
urls.py for edit is
url(r'^stuApp/(?P\d+)/$', views.edtStudent, name='edtStudent'),
method for edit inside view.py is :
def edtStudent(request,pk):
course = Course.objects.filter(pk=1).prefetch_related('students').select_related('dept')
if request.method =="POST":
form = CourseForm(request.POST,instance=Course)
if form.is_valid():
course = form.save(commit=False)
course.courseName = request.POST['courseName']
course.enrolledStu = request.Post['enrolledStu']
course.save()
course.save_m2m()
return redirect('liststudent')
else:
#form = CourseForm()
#return render(request, 'stuApp/edtStudent.html', {'form':form})
form = CourseForm(instance=course)
return render_to_response('edtStudent.html', {'form': form})
Html is :
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
it displays log from else but somehow doesn't display anything on html..
Thank you for your time....

filter always returns a queryset. But you need to pass a model instance, not a queryset, to the form. Use get instead.
course = Course.objects.filter(pk=1).prefetch_related('students').select_related('dept').get()

Related

Django & Form with SelectMultiple: null value in column x of relation y violates not-null constraint

I am facing the following error when trying to save the project after filling the form where i am choosing multiple tags for this project:
null value in column "tag_id" of relation "project_tags" violates not-null constraint
DETAIL: Failing row contains (10263, 10262, null). --> project_tags(id, project_id, tag_id)
The db model is simple: I have projects, and each project has tag(s). All is defined by the following models:
class Project(models.Model):
id = models.AutoField(primary_key=True)
client = models.ForeignKey(User, on_delete=models.CASCADE)
start_date = models.DateField()
end_date = models.DateField()
class Meta:
managed = False
db_table = 'project'
def get_absolute_url(self):
return reverse('project-detail', kwargs={'pk': self.pk})
class ProjectTag(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=30)
class Meta:
managed = False
db_table = 'project_tag'
def __str__(self):
return self.name
class ProjectTags(models.Model):
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
tag = models.ManyToManyField(ProjectTag)
class Meta:
managed = False
db_table = 'project_tags'
View is following:
#login_required
def add_project(request):
submitted = False
if request.method == "POST":
form1 = ProjectForm(request.POST)
form2 = ProjectTagsForm(request.POST)
if form1.is_valid() and form2.is_valid():
form1_part = form1.save(commit=False)
form1_part.client = request.user
form1_part.save()
project_id = Project.objects.get(id=form1_part.id)
form2_part = form2.save(commit=False)
form2_part.project = project_id
form2_part.save()
return HttpResponseRedirect('/project/new?submitted=True')
else:
form1 = ProjectForm
form2 = ProjectTagsForm
if 'submitted' in request.GET:
submitted = True
context = {'form1':form1
,'form2':form2
,'submitted':submitted
}
return render(request, 'home_page/add_project.html',context)
WIth following forms that are both in one template:
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ('start_date', 'end_date')
def __init__(self, *args, **kwargs):
super(ProjectForm, self).__init__(*args, **kwargs)
class ProjectTagsForm(forms.ModelForm):
class Meta:
model = ProjectTags
fields = ('tag',)
widgets = {
'tag': forms.SelectMultiple(attrs={'class': 'form-control','size': 12})
}
{% if submitted %}
Your project was submitted successfully!
{% else %}
<form action="" method=POST>
{% csrf_token %}
{{ form1.as_p }}
{{ form2 }}
<input type="submit" value="submit me" class="btn btn-secondary">
I understand the problem that after submitting the form it is not able to convert the selected tag names into tag_ids to fill the records (id,project_id,tag_id) and insert them to db table (as the table doesnt allow nulls as tag_id), but I have no idea how to fix, especially when it is practically copy paste of this Codemy video and its script where it worked https://youtu.be/x99hW1N8Nug

How to get objects from one model to other using ForeignKey in Django

I want to link models with there ids, I am having trouble in getting objects of foreignkey linked with id and creating queryset, I am new to Django I have searched alot about my problem but not getting answer.
models.py :
class Patient(models.Model):
name = models.CharField(max_length=200);
phone = models.CharField(max_length=20);
address = models.TextField();
Patient_id = models.AutoField(primary_key=True);
Gender= models.CharField(choices=GENDER,max_length=10)
consultant = models.CharField(choices=CONSULTANT,max_length=20)
def __str__(self):
return self.name
class Ipd(models.Model):
reason_admission = models.CharField(max_length=200, blank=False)
presenting_complaints = models.CharField(max_length=200,)
ipd_id = models.AutoField(primary_key=True)
rooms = models.ForeignKey(Rooms,on_delete=models.CASCADE,
blank=False)
date_of_admission = models.DateField(("Date"),
default=datetime.date.today)
patient =
models.ForeignKey(Patient,on_delete=models.CASCADE,blank=False)
def __str__(self):
return self.patient.name
forms.py :
class PatientForm(forms.ModelForm):
class Meta:
model = Patient
fields = ['name', 'phone', 'address', 'Patient_id', 'consultant',
'Gender']
class IpdForm(ModelForm):
class Meta:
model = Ipd
fields = ['patient','reason_admission','presenting_complaints',
'rooms','date_of_admission']
views.py:
#login_required
def ipd (request,patient_id):
p = Patient.objects.get(pk=patient_id)
if request.method=="POST":
formtwo = IpdForm(request.POST,instance=p)
if formtwo.is_valid() :
formtwo.user_id = request.user.id
if formtwo.save():
return HttpResponseRedirect('ipd_list.html',
messages.success(request, 'Patient is successfully updated.', 'alert-
success'))
else:
return render('ipd_list.html', messages.error(request,
'Data is not saved', 'alert-danger'))
else:
return HttpResponse(formtwo.errors)
else:
formtwo = IpdForm()
return render(request, 'newipd.html', {'p':p ,'form2':formtwo})
html :
<div class="card-panel">
<span class="blue-text text-darken-2">Name : {{p.name}}</span> <br> <span
class="blue-text text-darken-2">Phone : {{ p.phone }}</span><br>
</div>
I am having problem with queryset that allows me to use object of one model to another
Your question isn't very clear but if you want to get an Ipd queryset based on Patient id you would do :
qs = Ipd.objects.get(patient=patient_id)
If you want a list of Ipd's for a Patient you would do:
qs = Patient.idp_set.all()
In an html template to get all Ipds for a patient, you would use
{{ object.ipd_set.all }} .
You need to pass the patient as object.
If you want to loop through this you would need to use:
{% for ipd in object.ipd_set.all %}
do stuff
{% endfor %}
def listing(request):
queryset_li = Listing.objects.order_by('-list_date')
context = {
'listings': queryset_li,
}
return render(request, 'listings/listings.html', context)

saving form - many to many relationship

I am trying to save form based data in many to many relationship. My models is as follow:
class Student(models.Model):
stuName = models.CharField(max_length=100)
stuCity = models.CharField(max_length=100)
stuPhone = models.IntegerField(max_length=10)
stuNationality = models.CharField(max_length=50)
stuCreatedt = models.DateTimeField(default=timezone.now)
def __str__(self):
return '%s %s %s' % (self.stuName,self.stuCity,self.stuNationality)
class Dept(models.Model):
deptId = models.AutoField(primary_key=True)
deptName = models.CharField(max_length=100)
def __str__(self):
return '%s %s' % (self.deptId, self.deptName)
class Course(models.Model):
courseId = models.AutoField(primary_key=True)
courseName = models.CharField(max_length=100)
enrolledStu = models.IntegerField(max_length=3)
students = models.ManyToManyField(Student)
dept = models.ForeignKey(Dept, on_delete=models.CASCADE)
def __str__(self):
return '%s %s %s %s' % (self.courseName,self.enrolledStu,self.students,self.dept)
which i am trying to save. my view is
def addStudent(request):
if request.method == "POST":
form = CourseForm(request.POST)
if form.is_valid():
print(form.cleaned_data)
course = form.save(commit=False)
course.courseName = request.courseName
course.save()
form.save_m2m()
return redirect('lstDetail')
i tried without form.save_m2m() method but still its giving error.
AttributeError at /stuApp/new/
'WSGIRequest' object has no attribute 'courseName'
Request Method: POST
Request URL: http://127.0.0.1:8000/stuApp/new/
Django Version: 1.11.10
Exception Type: AttributeError
Exception Value:
WSGIRequest' object has no attribute 'courseName
Exception Location: C:\Users\PycharmProjects\learning\stuApp\views.py in addStudent, line 22
Python Executable: C:\Users\PycharmProjects\learning\venv\Scripts\python.exe
Python Version: 3.6.4
this is from html page. on console there isn't any error its just prints the query.
basically i am unable to save data with many to many fields and relationship.
my html is
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
urls py:
urlpatterns = [
url(r'^$',views.listStudent,name='liststudent'),
url(r'^stuApp/(?P<pk>\d+)/$', views.lstDetail, name='lstDetail'),
url(r'^stuApp/new/$', views.addStudent, name='addStudent'),
url(r'^stuApp/new/$', views.addStudent, name='addStudent'),
]
thank you for your help and time

ModelForm has empty fields list

Sorry for my poor english...
I've got a Model called Habitation :
class Habitation(models.Model):
propr = models.ForeignKey(Client, related_name="proprietaire")
locat = models.ForeignKey(Client, related_name="locataire", null=True, blank=True)
etage = models.CharField(max_length=2, blank=True)
numero = models.CharField(max_length=3, blank=True)
ad1 = models.CharField(max_length=64)
ad2 = models.CharField(max_length=64, blank=True)
cp = models.CharField(max_length=5)
ville = models.CharField(max_length=32)
def get_appareils(self):
return Appareil.objects.filter(habitation=self)
def selflink(self):
if self.id:
return 'Editer' % str(self.id)
else:
return 'Indéfini'
selflink.allow_tags = True
def __unicode__(self):
return u'%s - %s %s' % (self.ad1, self.cp, self.ville)
With his edit view :
def edit(request, habitation_id):
habitation = Habitation.objects.get(pk=habitation_id)
if request.POST:
form = HabitationForm(request.POST, instance=habitation)
if form.is_valid():
form.save()
return redirect('clients')
else:
form = HabitationForm(instance=habitation)
print form.fields
return render_to_response('habitations/edit.html', {
'habitation_id': habitation_id,
'form': form,
}, context_instance=RequestContext(request))
and his template :
<table>
<form action="/habitations/edit/{{ habitation_id }}/" method="post">
{{ form }}
{% csrf_token %}
{{ form.as_table }}
</form>
</table>
Form:
from django import forms
from client import models
class HabitationForm(forms.ModelForm):
class meta:
model = models.Habitation
fields = ('propr', 'locat', 'etage', 'numero', 'ad1', 'ad2', 'cp', 'ville',)
My view (or my ModelForm) doesn't retrive any field, so no more form field.
Is anybody has any suggestion ?
The meta class name in form should be Meta not meta.
Update your form to
from django import forms
from client import models
class HabitationForm(forms.ModelForm):
class Meta: #<---- define with capital M
model = models.Habitation
fields = ('propr', 'locat', 'tegae', 'numero', 'ad1', 'ad2', 'cp', 'ville',)

How to create and process a form with multiple same fields?

I'm really stuck with this. To show my problem I created a new Django project and started from scratch, focusing only on one single form.
What I'm trying to do is to create a form with several fields of the same name. I tried using modelformset_factory to achieve this but it looks to me like it's not what I really need.
Below is my code (also on dpaste) which currently works fine with one single field called name. How can I create and process a form which would have several name fields? Could somebody point me in the right direction?
# models.py
class Category(models.Model):
name = models.CharField(max_length=30, unique=True)
user = models.ForeignKey(User, blank=True, null=True)
class Meta:
verbose_name_plural = "Ingredience Categories"
def __unicode__(self):
return self.name
# forms.py
class CategoryForm(ModelForm):
class Meta:
model = Category
fields = ('name',)
# views.py
def home(request):
if request.method == 'POST':
catform = CategoryForm(request.POST)
catformInstance = catform.save(commit = False)
catformInstance.save()
return HttpResponseRedirect('')
else:
catform = CategoryForm()
context = {'catform': catform}
return render_to_response('home.html', context, context_instance=RequestContext(request))
# home.html template
<h3>Insert new Category</h3>
<form action="/" method="post" id="ingr-cat-form">{% csrf_token %}
{{ catform.as_p }}
<input type="submit" name="ingrCatForm" value="Save" />
</form>
UPDATE: to clarify, I want to allow user to insert several categories within one form. I think I'm getting close, here is my new version of views.py but it still stores just one category (the last one in the list):
def home(request):
if request.method == 'POST':
catform = CategoryForm(request.POST)
names = request.POST.getlist('name')
catformInstance = catform.save(commit = False)
for name in names:
catformInstance.name = name
catformInstance.save()
return HttpResponseRedirect('')
else:
catform = CategoryForm()
context = {'catform': catform}
return render_to_response('home.html', context, context_instance=RequestContext(request))
You cannot have fields with the same name (on the same Model). If you only need to change the html label in the html form, use
class Category(models.Model):
name = models.CharField(max_length=30, unique=True)
name2 = models.CharField(max_length=30, unique=True, verbose_name="name")
user = models.ForeignKey(User, blank=True, null=True)
or
class CategoryForm(ModelForm):
def __init__(self , *args, **kwargs):
super(CategoryForm, self).__init__(*args, **kwargs)
self.fields['name2'].label = "name"
Here is a working solution. Thanks to #YardenST for pointing me in the right direction. I managed to solve my initial problem by following this tutorial.
# models.py
class Category(models.Model):
name = models.CharField(max_length=30, unique=True)
user = models.ForeignKey(User, blank=True, null=True)
class Meta:
verbose_name_plural = "Ingredience Categories"
def __unicode__(self):
return self.name
# forms.py
class CategoryForm(ModelForm):
class Meta:
model = Category
fields = ('name',)
# views.py
def home(request):
if request.method == 'POST':
catforms = [CategoryForm(request.POST, prefix=str(x), instance=Category()) for x in range(0,3)]
if all([cf.is_valid() for cf in catforms]):
for cf in catforms:
catformInstance = cf.save(commit = False)
catformInstance.save()
return HttpResponseRedirect('')
else:
catform = [CategoryForm(prefix=str(x), instance=Category()) for x in range(0,3)]
context = {'catform': catform}
return render_to_response('home.html', context, context_instance=RequestContext(request))
# home.html template
<h3>Insert new Category</h3>
<form action="/" method="post" id="ingr-cat-form">{% csrf_token %}
{% for catform_instance in catform %} {{ catform_instance.as_p }} {% endfor %}
<input type="submit" name="ingrCatForm" value="Save" />
</form>