How can I insert data in two different models? - python

I'm newbie in coding, and I'm trying my first Django app.
This time I have three different models, but with a single form at the momment when I hit Save I want to save data on that form model and in the others 2 models.
So in my display I want to loop the other two models to show what I have.
Is that even possible?
models.py
class Personame(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Personlastname(models.Model):
last_name = models.CharField(max_length=128)
def __str__(self):
return self.last_name
class Personinfo(models.Model):
personame = models.CharField(max_length=128)
personlastname = models.CharField(max_length=128)
address = models.TextField()
phone_number = models.CharField(max_length=128)
hobbies =models.CharField(max_length=128)
def __str__(self):
return self.personame
forms.py:
class personform(forms.ModelForm):
personame = forms.CharField(label = "Name")
personlastname = forms.CharField(label = "Last Name")
class Meta:
model = Personinfo
fields = ["personame","personlastname","address","phone_number","hobbies"]
views.py:
def index(request):
queryset = Personame.objects.all()
queryset2 = Personlastname.objects.all()
qs = chain(queryset,queryset2)
form = personform(request.POST or None)
context = {
"qs": qs,
"form":form,
}
if form.is_valid():
instance = form.save()
return render(request, "index.html", context)
index.html:
<form method="POST" action="">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save!" />
</form>
<table >
<tr>
<th>Name</th>
<th>Last Name</th>
</tr>
{% for item in qs %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.last_name }}</td>
</tr>
{% endfor %}
</table>
Basically I want to save name in Personinfo and Personame, and I want to save last_name in Personinfo and Personlastname. So I can show Personame and Personlastname in template.
Can anyone help me please?
I would be very happy for your help... Thanks

Well your models don't make any sense at all. They really should be one model. you have not defined any relationship between any of the models. To do that you will have to add a OneToOneField or a ForeignKey. That effectively means you are having an extra column for each item of data. Totally redundant.
class Personinfo(models.Model):
name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
address = models.TextField()
phone_number = models.CharField(max_length=128)
hobbies =models.CharField(max_length=128)
def __str__(self):
return self.personame
This makes your life so much easier with simpler coding.

your models don't have class Meta , need to define the table name in class meta like :
class Meta:
managed = True
db_table = 'tableName'
Then u need to override save function in personform

Related

Trying to get Total Sold for each Item in E-commerce Django Project

I am trying to get the total no. of a sold item after payment is made.
When the order is paid ordered = models.BooleanField(default=False) become True
I have tried to add the context with the total sold but it didn't work so I kept it in the code below but commented it.
I have also tried to add a function with total count but I keep getting 'Item' object has no attribute 'order_set' I kept it below for reference
Here is the Item models.py
class Item(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
# def count_sold(self):
# return self.order_set.filter(ordered=True).count()
Here is the OrderItemmodels.py
class OrderItem(models.Model):
ordered = models.BooleanField(default=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
Here is the Order
class Order(models.Model):
items = models.ManyToManyField(OrderItem)
ordered = models.BooleanField(default=False)
Here is the views.py
class DesignerOnlyPostListView(ListView):
model = Item
template_name = "designer_only_posts.html"
context_object_name = 'items'
paginate_by = 6
def get_queryset(self):
user = get_object_or_404(User, username=self.kwargs.get('username'))
return Item.objects.filter(designer=user).order_by('-timestamp')
def get_context_data(self, **kwargs):
comments = Comment.objects.all()
# total_sold = Order.objects.all()
context = super().get_context_data(**kwargs)
context["total_comments"] = comments.count()
# context["total_sold"] = total_sold.count()
return context
Here is the template
{% for item in items %}
<tr>
<td>No. of Sold:</td>
<td>{{ item.total_sold.all.count }}</td>
</tr>
{% endfor %}
This is the template when I tried to use the function for count_sold
<tr>-->
<!-- <td>No. of Reviews:</td>-->
<!-- <td>{{ item.count_sold }}</td>-->
<!-- </tr>
Item doesn't have order_set, because there's no relation between those two Models.
Item is related to OrderItem
OrderItem is related to Order
Maybe you can try something like:
class Item(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
#property
def count_sold(self):
return self.orderitem_set.filter(ordered=True).count()
and for the template
{% for item in items %}
<tr>
<td>No. of Sold:</td>
<td>{{ item.count_sold }}</td>
</tr>
{% endfor %}

Django : Allow user to select the right forms for registering

I'm new to Django and I would like to create a "modular registering form".
The aim of this form is to be able to select the needed form (related to the user type) to complete the registration of a new user.
models.py
class UserTypes(models.Model):
USER_TYPES = (
('simple', 'simple'),
('advanced', 'advanced')
)
user_type = models.CharField(max_length = 10, choices = USER_TYPES)
class FirstClass(models.Model):
username = models.CharField(max_length=100, null=True)
first_name = models.CharField(max_length=100, null=True)
last_name = models.CharField(max_length=100, null=True)
class SecondClass(models.Model):
link_to_first_class = models.OneToOneField(FirstClass, on_delete=models.CASCADE, null=True)
other_informations = models.CharField(max_length=200, null=True)
forms.py
class UserTypesForm(forms.ModelForm):
class Meta:
model = UserTypes
fields = '__all__'
class FirstClassForm(forms.ModelForm):
class Meta:
model = FirstClass
fields = '__all__'
class SecondClassForm(forms.ModelForm):
class Meta:
model = SecondClass
fields = '__all__'
exclude = ('link_to_first_class',)
views.py
#transaction.atomic
def modular_register(request):
if request.method == 'POST':
user_types = UserTypesForm(request.POST)
first_form = FirstClassForm(request.POST)
second_form = SecondClassForm(request.POST)
if user_types_form.is_valid() and first_form.is_valid() and second_form.is_valid():
first_form.save()
first_class_instance = FirstClass.objects.filter(username = first_form.data['username'])[0]
second_class = SecondClass(link_to_first_class = first_class_instance,
other_informations = second_form.data['other_informations'])
second_class.save()
messages.success(request, 'Account created successfully')
return redirect('modularregister')
else:
user_types_form = UserTypesForm()
first_form = FirstClassForm()
second_form = SecondClassForm()
return render(request, 'blog/modularregister.html', {'user_types_form':user_types_form, 'first_form': first_form, 'second_form' : second_form} )
template
<form method="post" >
{% csrf_token %}
<table>
{{ user_types_form.as_table }}
{{ first_form.as_table }}
{{ second_form.as_table }}
<tr>
<td><input type="submit" name="submit" value="Register" /></td>
</tr>
</table>
</form>
Explanation :
If the user select "simple" as user_type only the FirstClassForm need to appear.
If the user select "advanced" the two forms (FirstClassForm and SecondClassForm) need to appear.
So I read some articles about the "OnChange" function which requires the writing of a script.
So here is my question :
According to you, what is the best way to select only the needed forms and how to handle that in the view ?

Display foreign key value in django template

I've looked through the similar questions and was unable to find a solution that fits or I'm missing something? I have two models(SafetyCourse and SafetyCourseTaken) I have a foreign key relationship that points from "safety courses taken" to safety course, shown below:
models.py
class SafetyCourse(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=128, unique=True)
def __str__(self):
return self.name
class SafetyCoursesTaken(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
profile = models.ForeignKey(EmployeeProfile, on_delete=models.CASCADE)
course = models.ForeignKey(SafetyCourse, on_delete=models.CASCADE, related_name='course_name')
conducted_date = models.DateTimeField(null=True, blank=True)
expiration_date = models.DateTimeField(null=True, blank=True)
class Meta:
verbose_name_plural = 'Safety Courses Taken'
views.py
class ManageSafetyCourseTakenView(LoginRequiredMixin, generic.ListView):
login_url = reverse_lazy('users:login')
model = SafetyCoursesTaken
template_name = 'ppm/courses-taken.html'
paginate_by = 10
# override get_queryset to only show training related to employee profile
def get_queryset(self):
pk = self.kwargs['pk']
return SafetyCoursesTaken.objects.filter(profile_id=pk)
course-taken.html(template)
{% for course_taken in object_list %}
<tr>
<td>{{ course_taken.course_id}}</td>
</tr>
{% endfor %}
I've tried a number of solutions to similar questions but was unable to find a correct one. I've tried: course_taken.course_name_set.select_related, course_taken.course_name_set, and a few others. What I want to do is just display the name of the course instead of the course id. What am I doing wrong?
Looking at your schema, I think it should be this in the template:
{% for course_taken in object_list %}
<tr>
<td>{{ course_taken.course.name }}</td>
</tr>
{% endfor %}

Using render field for select option in django

I am using widget_tweaks in my django project. For an input tag, I am using it like :
{% render_field form.enrollment_no class='form-control' id='id_enrollment_number' placeholder='Enrollment Number' type='text' %}
Now, I want to achieve something similar for <select> tag:
<select class='form-control' id='id_faculty'>
{% for faculties in faculty %}
<option value="{{ faculties }}">{{ faculties }}</option>
{% endfor %}
</select>
But, I think I am doing something wrong, because it would not help while checking the validity on form submit. Please help me to solve this.
Edit 1:
Also, I am getting faculty from a different model:
form = StudentForm()
faculty = Faculty.objects.all()
return render(request, 'index.html',{'form' : form,'faculty' : faculty}).
Studen Model :
class Student(models.Model):
"""here goes model for users"""
def __str__(self):
return self.name
name = models.CharField(max_length=200)
enrollment_no = models.CharField(max_length=10)
Faculty Name:
class Faculty(models.Model):
faculty_name = models.TextField()
def __str__(self):
return self.faculty_name
Student Form class:
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = '__all__'
Other tables:
class Faculty(models.Model):
faculty_name = models.TextField()
def __str__(self):
return self.faculty_name
class Department(models.Model):
faculty = models.ForeignKey(Faculty,on_delete=models.CASCADE)
department_name = models.TextField()
def __str__(self):
return self.department_name
class Course(models.Model):
student = models.ForeignKey(Student,on_delete=models.CASCADE)
department = models.ForeignKey(Department,on_delete=models.CASCADE)
course_name = models.TextField()
def __str__(self):
return self.course_name

Django Multiple ForeignKey Navigation

I'm building a shopping cart. In my shopping cart an item can be composed of other items. I need to display a set of items with their corresponding associated parts in a single template. I know how to show a single item with its corresponding parts in a template, but I can't seem to figure out how to show more than one item, each with its own list of included parts.
I have fiddled with every permutation of tags in the template file:
# checkout.html
{% for item in cart_items %}
<tr>
<td class="left">
{{ item.name }}
<ul>
{% for part in item.product.buildpart.part_set.all %}
<li>{{ part.name }}
{% endfor %}
</ul>
</td>
<td>${{ item.price }}</td>
<td>{{ item.quantity }}</td>
<td class="right">${{ item.lineItemTotal }}</td>
</tr>
{% endfor %}
Here is the vew that generates the template:
# views.py
def checkout(request):
cart_items = get_cart_items(request)
<snip>
return render(request, 'checkout.html', locals())
And here's the get_cart_items() function that returns all the items in the user's shopping cart:
# cart.py
def get_cart_items(request):
""" return all items from the current user's cart """
return CartItem.objects.filter(cart_id=get_cart_id(request))
Here's the CartItem model:
# models.py
class Item(models.Model):
cart_id = models.CharField(max_length=50)
quantity = models.IntegerField(default=1)
product = models.ForeignKey(PartModel, unique=False)
class Meta:
abstract = True
<snip>
class CartItem(Item):
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['date_added']
verbose_name = "Cart Item"
<snip>
The 'product' field is a ForeignKey to the PartModel model:
# models.py
class PartModel(models.Model):
family = models.ForeignKey(PartFamily)
name = models.CharField("Model Name", max_length=50, unique=True)
slug = models.SlugField(help_text="http://www.Knowele.com/<b>*slug*</b>",
unique=True)
<snip>
buildpart = models.ManyToManyField('self', through='BuildPart',
symmetrical=False, related_name='+')
class Meta:
ordering = ['name']
verbose_name = "Product Model"
<snip>
The PartModel model has a ManyToMany relationship with itself through the buildpart field and the BuildPart model to facilitate the notion of catalog items that can be composed of other catalog items:
# models.py
class Build(models.Model):
build = models.ForeignKey(PartModel, related_name='+')
part = models.ForeignKey(PartModel, related_name='+')
quantity = models.PositiveSmallIntegerField(default=1)
class Meta:
abstract = True
unique_together = ('build', 'part')
def __unicode__(self):
return self.build.name + ' with ' + str(self.quantity) + ' * ' + \
self.part.family.make.name + ' ' + self.part.name
class BuildPart(Build):
pass
class Meta:
verbose_name = "Build Part"
I can't seem to make the necessary ForeignKey traversals in the template (listed above) in order to get all the parts associated with the user's items in the CartItem model. Is it something I'm not doing right in the template or am I not packaging up the right QuerySets in my view?
The second part of this issue is that once I get those parts, I need them to show up in the order specified in the 'order' integer field of the PartType model:
# models.py
class PartType(models.Model):
name = models.CharField("Part Type", max_length=30, unique=True)
slug = models.SlugField(unique=True)
order = models.PositiveSmallIntegerField()
description = models.TextField(blank=True, null=True)
class Meta:
ordering = ['name']
verbose_name = "Product Type"
def __unicode__(self):
return self.name
class PartFamily(models.Model):
make = models.ForeignKey(PartMake)
type = models.ForeignKey(PartType)
name = models.CharField("Family Name", max_length=30,
unique=True)
slug = models.SlugField(unique=True)
url = models.URLField("URL", blank=True, null=True)
description = models.TextField(blank=True, null=True)
class Meta:
ordering = ['name']
verbose_name = "Product Family"
verbose_name_plural = "Product Families"
def __unicode__(self):
return self.name
So as you can see, in the PartModel model, the 'family' field is a ForeignKey to the PartFamily model, and in the PartFamily model the 'type' field is a ForeignKey to the PartType model, within which is the all-important 'order' field that the parts need to be ordered by.
I hope this makes sense and you can see why this is so complicated for a noob like me.
Just iterate on item.product.buildpart.all:
{% for item in cart_items %}
[...]
{% for part in item.product.buildpart.all %}
{{ part.name }}[...]
{% endfor %}
{% endfor %}

Categories