currently I'm trying to show part quantity (quan) together with part name in the dropdown. I have a Part table that carries the part name and part quantity and this table called as ForeignKey into the Order table. So, in the Order form during choose the part name from the part dropdown, I would like to show part quantity as well besides the part name. Any idea to make it like that?
models.py
class Part(models.Model):
partno = models.CharField(max_length=50)
partname = models.CharField(max_length=50)
quan = models.PositiveIntegerField(default= 0)
def __str__(self):
return '{}, quantity - {}'.format(self.partname, self.quan)
class Order(models.Model):
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
part = models.ForeignKey(Part, on_delete=models.CASCADE)
views.py
def create_order(request):
from django import forms
form = OrderForm()
if request.method == 'POST':
for form_data in forms_data:
forms = OrderForm(request.POST)
if forms.is_valid():
supplier = forms.cleaned_data['supplier']
product = forms.cleaned_data['product']
part = forms.cleaned_data['part']
order = Order.objects.create(
supplier=supplier,
product=product,
part=part,
)
return redirect('order-list')
context = {
'form': form
}
return render(request, 'store/addOrder.html', context)
HTML
<form action="#" method="post" id="form-container" novalidate="novalidate">
{% csrf_token %}
<div class="form-group">
<label for="product" class="control-label mb-1">Product</label>
{{ form.product }}
</div>
<div class="form-group">
<label for="supplier" class="control-label mb-1">Supplier</label>
{{ form.supplier }}
</div>
<div class="form-group">
<label for="part" class="control-label mb-1">Part Name</label>
{{ form.part }}
</div>
</form>
You will have to write "__ str __"(without spaces between str and __) method for model 'Part'
def __str__(self):
return '{}, quantity - {}'.format(self.partname, self.quan)
Check this post also: What is doing __str__ function in Django?
Related
I have a django project where I have a list with checkboxes, to select and assign students to teachers.
I have attached my code below - I am getting no errors, but it doesn't seem to be assigning the student to the "students" many-to-many field in my "teachers" model.
I have a GET function that is called earlier to select the teacher, then it is meant to pull that GET record and assign the student to that teacher.
Any ideas?
Views.py
if 'assign_student' in request.POST:
form = StudentForm(request.POST)
selected = request.GET['select_teacher']
selected_teacher = Teacher.objects.all().filter(pk=selected)[0]
if form.is_valid():
student_selected = request.POST('assign_student')
student = Student.objects.all().filter(pk=student_selected)[0]
selected_teacher.students.add(student)
Template.html
<div class="student-list">
{% for instance in all_students %}
<div class="input-group" style="border-bottom: 1px solid;">
<div class="item-details">
<div class="form-check">
<form method="POST" class="form-group" name="assign_student">
{% csrf_token %}
<input onChange="this.form.submit()" class="form-check-input" type="checkbox" value={{ instance.pk }} id="flexCheckDefault" name="assign_student">
</form>
<p>
<b>{{ instance.fullname }}</b>
<br>
{{ instance.homeschool }} - {{ instance.schoolclass }} Class
</p>
</div>
</div>
</div>
{% endfor %}
</div>
Models.py
class Teacher(models.Model):
fullname = models.CharField(max_length=10000,verbose_name='Full Name')
firstname = models.CharField(max_length=10000,verbose_name='First Name')
lastname = models.CharField(max_length=10000,verbose_name='Last Name')
school = ForeignKey(School,on_delete=models.CASCADE,verbose_name='School')
creationuser = ForeignKey(CustomUser,on_delete=models.CASCADE)
students = models.ManyToManyField(Student)
class Role(models.TextChoices):
principal = 'principal'
classroomteacher = 'classroom teacher'
assistantprincipal = 'assistant principal'
role = models.CharField(
max_length=10000,
choices=Role.choices,
verbose_name='Role',
)
email = models.EmailField(verbose_name='Email Address')
def __str__(self):
return self.fullname
The reason it is not working is because you are using queries by using filters etc. Thus you are returned a query set instead of an object.
Instead you should use the get_object_or_404().
Furthermore, you are saving the data for the session and not in the database. You should use students.save() to save it in the DB.
You can do something like this
from django.shortcuts import get_object_or_404
if 'assign_student' in request.POST:
form = StudentForm(request.POST)
selected = request.GET['select_teacher']
selected_teacher = get_object_or_404(Teacher, pk=selected)
if form.is_valid():
student_selected = request.POST('assign_student')
student = get_object_or_404(Student, pk=student_selected)
selected_teacher.students.add(student)
selected_teacher.save() #saving the teacher model object
selected_teacher.students.save() #saving the student model object
Ah im silly!
I fixed it, I was trying to get a "if form.is_valid()" when i'm not posting a full form - removed that and all is working now.
I am new in Django and i am making a typical CRUD app. In the "add" section, in the comment textarea this message appears "
<django.db.models.query_utils.DeferredAttribute object at 0x03B446A0>"
and i dont know what to do. I had tried multiples solutions in other stackoverflow questions but i cant find the solutions!
Here's the code
class Turno(models.Model):
date = models.DateTimeField()
person = models.ForeignKey('Person', on_delete=models.CASCADE)
medic = models.ForeignKey('Medic', on_delete=models.CASCADE)
observations = models.CharField(blank=True, max_length=255)
def __str__(self):
return f'{self.date} {self.person} {self.medic}'
def new_turn(request):
if request.method == 'POST':
turnFormPost = TurnForm(request.POST)
if turnFormPost.is_valid():
turnFormPost.save()
return redirect("admin_index")
turnForm = TurnForm(instance=Turno)
context = {
'form':turnForm
}
return render(request,"turn_new.html", context)
class TurnForm(ModelForm):
class Meta:
model = Turno
fields = '__all__'
widgets = {
'date': DateTimeInput(attrs={'type':'date'}),
'observations': Textarea(attrs={'rows':5, 'cols':50})
}
-turn_new.html
<div class="container">
<h2>New Turn</h2>
<form method="POST">
{% csrf_token %}
<table>
{{form}}
</table>
<button type="submit" class="btn btn-primary">Create</button>
</form>
<div>
Back to index
</div>
</div>
in the textarea of 'observations' in 'turn_new.html' the message that appears is this
"<django.db.models.query_utils.DeferredAttribute object at 0x03B446A0>"
I'm creating a simple ratemyteacher/prof clone. The issue is that when going trying to add a Review object via my view, I get NOT NULL constraint failed: rate_review.review_id (app name is rate). It works fine when adding via /admin. Also, adding other models work fine.
Here's the view where it occurs:
def add_review(request, teacher_id):
form = ReviewForm()
if request.method == 'POST':
form = ReviewForm(request.POST)
if form.is_valid():
ip = request.META.get('HTTP_CF_CONNECTING_IP')
if ip is None:
ip = request.META.get('REMOTE_ADDR')
form.customSave()
messages.success(request, 'Review added.')
else:
form = ReviewForm(request.POST)
return render(request, 'rate/add_review.html', {'form': form})
return render(request, 'rate/add_review.html', {'form': form})
Here is the form (truncated to exclude loads). I'm using this to render forms:
<form method="POST">{% csrf_token %}
<div class="field">
<label class="label">Stars (whole numbers only)</label>
<div class="control">
{% render_field form.stars class+="input" %}
</div>
</div>
<div class="field">
<label class="label">Review subject</label>
<div class="control">
{% render_field form.subject class+="input" %}
</div>
</div>
<div class="field">
<label class="label">Review text</label>
<div class="control">
{% render_field form.text class+="textarea" placeholder="Review text" rows="10" %}
</div>
</div>
<div class="field">
<label class="label">Username</label>
<div class="control">
{% render_field form.author class+="input" placeholder="eg. ReviewerMan21, John Smith" %}
</div>
</div>
<button type="submit" class="button">Add review</button>
</form>
My models.py:
class Teacher(models.Model):
grade = models.IntegerField()
name = models.CharField(max_length=35)
subject = models.CharField(max_length=50)
ip = models.CharField(max_length=14)
approved = models.BooleanField(null=True, blank=True)
class Review(models.Model):
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
text = models.TextField()
subject = models.CharField(max_length=120)
author = models.CharField(max_length=35)
ip = models.CharField(max_length=14)
date = models.DateTimeField(auto_now_add=True)
stars = models.PositiveSmallIntegerField()
My forms.py:
from django import forms
from .models import Teacher, Review, Grade
from django.core import validators
class ReviewForm(forms.ModelForm):
class Meta:
model = Review
fields = ('subject', 'text', 'stars', 'author')
def customSave(self, ip):
lv = self.save(commit=False)
lv.ip = ip
lv.save()
return lv
class TeacherForm(forms.ModelForm):
class Meta:
model = Teacher
fields = ('subject', 'name', 'grade')
def customSave(self, ip):
lv = self.save(commit=False)
lv.ip = ip
lv.save()
return lv
Things I've tried:
Resetting/flushing the DB
Commenting out ip, author & stars
Adding blank=True, null=True to ip, stars and author
Migrating DB
Edit: I've fixed (thanks to the answer below) by changing customSave in ReviewForm to this, and then passing the teacher variable from my view:
def customSave(self, ip, teacher):
lv = self.save(commit=False)
lv.ip = ip
lv.teacher = teacher
lv.save()
return lv
Your error shows that review_id is None (null). I notice that your ForeignKey field to Teacher on the Review model is named review instead of teacher, which would indicate the review_id really belongs to a Teacher object.
I noticed the first line of your view add_review method, you get a Teacher object but never do anything with it. Did you intent to set the teacher ('review' field) on your newly created review to this teacher instance?
I spend a lot of time in google and find a few solutions for my problem
but none of them works :((
models :
class Album(models.Model):
name = models.CharField(max_length=100)
author = models.CharField(max_length=100)
picture_address = models.TextField(max_length=1000)
creation_year = models.IntegerField(default=-1)
rate = models.IntegerField(default=0)
class Music(models.Model):
name = models.CharField(max_length=100)
cover = models.ImageField(upload_to=upload_destination)
album_id = models.ForeignKey(Album, on_delete=models.CASCADE)
and here is form :
class music_create_form(forms.ModelForm):
album_options = [('', '')]
for album in models.Album.objects.all():
album_options.append((album,album.name))
name = forms.CharField(required=True
, widget=forms.TextInput(attrs={'class': "normal_padding form-control"}))
cover = forms.FileField(required=True
, widget=forms.FileInput(attrs={'class': "normal_padding", 'accept': "image/jpeg"}))
album_id = forms.Field(required=True
,
widget=forms.Select(attrs={'class': "normal_padding form-control"}, choices=album_options))
class Meta:
model = models.Music
fields = [
'name', 'cover', 'album_id'
]
and here is view :
def create_music(request):
form = forms.music_create_form(request.POST or None, request.FILES or None)
context = {'form': form}
if request.method == "POST":
if form.is_valid():
print(form)
data = form.save(commit=False)
data.save()
context['action_done'] = True
return render(request, 'music/create_music.html', context)
when i try to add new model with that form , i got the error at this line : " if form.is_valid() "
Cannot assign “'Album object (6)'”: “Music.album_id” must be a “Album” instance
This is my form in template :
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="container">
<div class="form-inline">
<h5 class="normal_padding">Music Name:</h5>
{{ form.name }}
</div>
<div class="form-inline">
<h5 class="normal_padding">Music Cover:</h5>
{{ form.cover }}
</div>
<div class="form-inline">
<h5 class="normal_padding">Album:</h5>
{{ form.album_id }}
</div>
<button type="submit" class="btn btn-primary">save data</button>
</div>
</form>
You shouldn't use forms.Field. In this case, you should use a ModelChoiceField, that will take care of getting the choices for you.
class MusicCreateForm(forms.ModelForm):
name = forms.CharField(required=True
, widget=forms.TextInput(attrs={'class': "normal_padding form-control"}))
cover = forms.FileField(required=True
, widget=forms.FileInput(attrs={'class': "normal_padding", 'accept': "image/jpeg"}))
album_id = forms.ModelChoiceField(queryset=Album.objects.all(),
widget=forms.Select(attrs={'class': "normal_padding form-control"}))
As an aside, it would be better to rename your ForeignKey and form field to album. That way music.album is the related album and music.album_id is it's id. At the moment, music.album_id is the album and music.album_id_id is the id.
What I want to do is some of the fields in my form to be automatically added according to the previous value. Let me show you my example:
my model
class Measurement(models.Model):
group = models.CharField(max_length=250)
subgroup = models.CharField(max_length=250)
number=models.PositiveIntegerField(default=1)
voltage= models.PositiveIntegerField()
comment = models.TextField(default='no comment')
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.group
forms.py
class MeasurementForm(forms.ModelForm):
class Meta:
model = Measurement
fields = ['group','subgroup','number','voltage','comment']
my views.py
def measurement(request):
if request.method == "POST":
form = MeasurementForm(request.POST, request.FILES)
if form.is_valid():
measurement = form.save(commit=False)
measurement.save()
return redirect('data:measurement')
else:
form = MeasurementForm()
context = {'form': form,}
template = 'data/measurement.html'
return render(request, template, context)
html.file
<div class="panel panel-primary">
<div class="panel-heading">
<h4>Add a measurement</h4>
</div>
<div class="panel-body">
<form method='POST' enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button type = 'submit' class="btn btn-success">Save</button>
</form>
</div>
</div>
What I would like to have though is the fields group, subgroup and number to be automatically generated according to what I entered before.
For example, first measurement I enter:
Group:House Subgroup:Light Number:1 Voltage: 10 Comment: No comment
Once I click save I want the fields Group, Subgroup and Number to have the following information already:
Group:House Subgroup:Light Number:2 Voltage: 12 Comment: No comment
The next one:
Group:House Subgroup:Light Number:3 Voltage: 15 Comment: No comment
In order to add only my measurement and save time. However that does not mean that I can't change the Group, Subgroup or Number fields.