Multiple Django Forms on Single Page - python

I'm trying to create a form to input scores for a round of golf. A standard round of golf is 18 holes, so the form should create 18 instances of 'Score' once submitted. How would I go about creating a form that contains a single dropdown for 'player' and 18 text fields for strokes on each hole? Below are the models being used:
class Score(models.Model):
hole = models.ForeignKey(Hole, on_delete=models.CASCADE)
player = models.ForeignKey(Player, on_delete=models.CASCADE)
strokes = models.IntegerField(default=0)
class Player(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
class Hole(models.Model):
number = models.IntegerField()

Have a look at Django Inline Formsets. This allows you to include multiple forms per view and the inline formset allows you to work with objects related by a foreign key.
It is relatively easier when you know the exact amount of forms you need to include in your template. However, if you want to dynamically include forms in your template then you will need to look into adding some javascript to provide this functionality.

Related

Django - Team/User relationships

I'm at a loss... I'm just learning Django and I am really rather confused about how to make a field work the way I would like it to.
I understand that Django has a native "Groups" model. However, I am looking to build my own teams model for customization and practice.
Here is my models.py file for my Users app:
from django.db import models
from django.contrib.auth.models import User
class Team(models.Model):
members = models.ManyToManyField(User)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
admin = models.BooleanField("Admin Status")
Here's where I'm confused. I would like to be able to call the team that the user is part of directly from User.Profile. So, I want to add a field to my Profile class that will automatically populate with the team name when a user is added to a team.
A potential problem I can see is that, currently, I can assign a user to multiple teams. This doesn't bother me, perhaps I can have a Profile model field that automatically populates with a list of all the teams that the user is associated with. Regardless, I can't figure out what type of field I would need to use, or how to do this.
Does that make sense?
A potential problem I can see is that, currently, I can assign a user to multiple teams.
Indeed, you can however easily retrieve the Teams the myprofile object is a member of with:
Team.objects.filter(members__profile=myprofile)
You thus can make a property for the Profile model:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
admin = models.BooleanField("Admin Status")
#property
def teams(self):
return Team.objects.filter(
members__profile=self
)
Then you thus access the Teams of a myprofile with myprofile.teams.
So, I want to add a field to my Profile class that will automatically populate with the team name when a user is added to a team.
From my limited knowledge of database, you can add a name field to your Team model.
Keeping in mind your requirement as mentioned in question, i would suggest you to use django reverse relations to get all the teams the profile is associated with
user_teams = User.objects.get(id='user_id').profile_set.all()[0].team_set.all()
to know more about django ORM reverse relation, here is a very short article

How to save the data that has same model but with different data in Django

I'm working on a mini project which uses Django 1.8. The aim is to build a small billing app. So, I've created two models, Bill and Product, as follows.
#bill/models.py
class Bill(models.Model):
date_of_issue = models.DateField()
name = models.CharField(max_length=50, default="N/A", null=True)
address = models.CharField(max_length=150, default="N/A", null=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
def __str__(self):
return "{} {}".format(self.input_name, self.date_of_issue)
class Product(models.Model):
bill = models.ForeignKey(Bill, on_delete=models.CASCADE)
description = models.CharField(max_length=100, default="N/A")
quantity = models.IntegerField(default=0)
total = models.IntegerField(default=0)
By seeing the model, you can tell that my approach is to create Bill and Product tables and connect the Product to Bill via ForeignKey. Now, the thing is that a single bill will contain at least one product. If there are more than one product, how should I write my views in views.py. I'm a beginner in the Django development. If a Bill contains a single Product then I can write its view. But how can I store multiple Product which have different data and storing it in database.
For Example
The user will enter the name and address of the customer. Then the user will enter the details of products. Now I want to generate the Product modelform more than once (depends upon the number of products added by user). How can I accomplish this ?
Assuming
1) multiple products can be bought at once (and thus be part of one bill) and
2) one product can be bought multiple at any time (and thus be part of many bills)
a simple foreign key is the wrong modelling attempt. Instead of a m:1 relation you need a m:n relation - and thus a ManyToManyField. With a ManyToManyField you can add multiple products to one bill or have mutiple products added to multiple bills. In django-admin it's useful (and I recommend it) to put ManyToManyFields as filter_horizontal which eases the use of this field.
Plus, django will automatically resolve your m:n relation with an additional third database table, so you don't need to take care of this.

Django: Creating multiple class instances on a single webpage, with Foreign Key dependencies

I have the following code in my models.py:
class Application(models.Model):
team_name = models.CharField(max_length=100)
...
class Participant(models.Model):
name = models.CharField(max_length=100)
grade = models.SmallIntegerField(choices=GRADE_CHOICES, blank=True, null=True)
application = models.ForeignKey(Application, related_name="participants")
...
i.e. There are multiple Participants, and each Participant will be on a single application. (It is defined that each Application will have exactly 8 Participants).
The intended purpose of this code is that a user will be able to create a new application, on which he/she will name 8 Participants. When the Application is created, 8 new instances of Participants should also be created and linked such that each Participant has the newly created Application as its Foreign Key.
I am currently struggling to create a form/view that will handle this creation process. I want the user to be a presented a single webpage that presents input forms that allow the user to create a new Application (name, etc.), along with 8 new Participants (each having a name, grade, etc.)
My current forms.py has:
class ApplicationForm(forms.ModelForm):
"""
A form that edits an application and all of its participants.
"""
nationality = forms.CharField(disabled=True, required=False)
class Meta:
model = Application
fields = '__all__'
But I realize that this does not display to the user what is needed to create 8 new Participants with the creation of this Application. How can I modify my forms.py to include space for the user to create 8 Participants with the creation of an Application?
The only solution I can come up with is to manually list 8 Participant form calls in a single view, but I feel that there must be a better solution.
What you are looking for is django formsets
A formset is a layer of abstraction to work with multiple forms on the
same page. It can be best compared to a data grid. Let’s say you have
the following form:
There is also a ModelFormSet
Like regular formsets, Django provides a couple of enhanced formset
classes that make it easy to work with Django models.
These can be used to create several instances of a given model in a single page. The only trouble is that it has a bit of a learning curve and the user experience isn't as great as what you might get with Angular or React.

Pass model objects to choices field in django

I have a model called Student that has a manytomany relationship with a model called Courses. I have another model called Attend in which I want to get all the courses the student is taking and pass it in as a select menu containing the courses the student is taking. I tried to get the id using the foreign key "student" and then get courses belonging to that student and put it in a list and pass it to choices but it didn't work obviously. I would like to know how I can get the courses belonging to the student to appear in the select menu.
Here is my model.
class Attend(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE, default="")
time_signed_in = models.DateTimeField(auto_now_add=True)
isSignedIn = models.BooleanField(default=False)
# Below does not work, I get an error 'ForeignKey' object has no attribute 'id'
#courses = User.objects.get(id=student.id).courses
course = models.ForeignKey(Course, on_delete=models.CASCADE)
To render the courses the student is taking you should try using django forms.
If I understand correctly, you want a form that uses ModelMultipleChoiceField:
Allows the selection of one or more model objects, suitable for
representing a many-to-many relation.
class AttendForm(forms.Form):
courses = forms.ModelMultipleChoiceField(queryset=Courses.objects.filter(student__id=id))
That exapmple would only work to show the data to the user and then retrieving its choice. There is a slightly different approach to this case and that is using a ModelForm.
Every ModelForm also has a save() method. This method creates and saves a database object from the data bound to the form.
ModelForm is a "database driven" form in which you can perform many task involving calls to the database easily.
Note: The queryset I used in the example is just an example, you dont have to use it that way.

Django modeling problem, need a subset of foreign key field

I intend to create an app for categories which will have separate category sets (vocabularies) for pages, gallery, product types etc. So there will need to be two models, vocabulary and category.
The categories/models.py code might be something like this:
class Vocabulary(models.Model):
title = models.CharField()
class Category(models.Model):
title = models.CharField()
vocabulary = models.ForeignKey(Vocabulary)
From my pages, blogs, gallery, etc apps how I will need a ForeignKey field to categories:
class Page(models.Model):
title = models.CharField()
content = models.TextField()
category = models.ForeignKey('categories.Category')
This will of course list all available categories in the admin app. If I have a product I want only the product categories to be avaialble. How can I filter the available categories to a specific vocabulary?
I'm learning Django and not really sure where to begin. Maybe I have the whole model wrong? If there are any apps which already do it please let me know.
Filtering of selection like this is done in the form using a queryset, or in the admin interface with limit_choices_to.

Categories