I'm just new using Django. I just created my models and migrate information to my sqlite3 database using the .cvs import module. This are my modules:
class Backlog(models.Model):
sales_order = models.CharField(max_length=30)
po_number = models.CharField(max_length=30)
order_number = models.IntegerField(blank=True)
line_number = models.IntegerField(blank=True)
ship_Set = models.IntegerField(blank=True)
product_id = models.CharField(max_length=30)
ordered_quantity = models.IntegerField(blank=True)
class Material(models.Model):
product_id = models.CharField(max_length=50)
tan_id = models.CharField(max_length=50)
Now that I have the information inside my tables I want to do the following:
Find if product_id from Backlog is in Material's model, once it finds it verify the first two digits from the tan_id. If is 74 classify as '1', if is 800 classify as '3' else set as '2'. (tan_id format commonly are 74-102345-03, 800-120394-03)
My two questions are:
How to do that and if I have to create a new column to add the information from every product_id.
Ok well given your current models, here is a possible solution to the problem you are having:
for backlog in Backlog.objects.all():
try:
material = Material.objects.get(product_id = backlog.product_id)
if material.tan_id[0:2] == '74':
# Classify as 1
elif material.tan_id[0:2] == '80':
# Classify as 3
else:
# Classify as 2
except Material.DoesNotExist:
print("This material is not in backlog")
continue
This code should loop over every instance of Backlog you have in your database and then try to find the associated Material. In the event it doesn't find a Material (in your case there is no backlog), objects.get() raises an exception that it doesn't exist, we print it's not there and continue on with the loop. If it is we classify it as you specified. Might require a slight bit of tweaking but it should give you the bones of what you want to fix this problem. Let me know if it doesn't.
Related
I have a model called participants as below
class participants(models.Model):
username= models.CharField(max_length =50)
votes = models.IntegerField(default=0)
voted_by = ?
Votes is the total number of votes given by users and single user can vote multiple times. If the user have voted then the user should wait 1 hour to vote again. Now i am wondering, how can i store users id in a way that it would be easier to know who voted how many times and the recent date and time the user have voted.
Can someone suggest me or refer some examples that i can solve this problem.
You can create another model (eg. VotesHistory)...
class VotesHistory(models.Model):
class Meta:
verbose_name = "Vote Log"
verbose_name_plural = "Vote Logs"
time = models.DateTimeField(auto_now=True, verbose_name="Time")
uid = models.IntegerField(verbose_name="Voter's UserID")
pid = models.IntegerField(verbose_name="Voted UserID")
Now, when user 1 will vote user 2, you can create an entry such as,
VotesHistory(uid=user1.id, pid=user2.id).save()
This kind of problem is generally solved by using a ForeignKey reference.
# class name should begin with a capital letter and should be singular for a model
class Participant(models.Model):
username = models.CharField(max_length =50)
class Vote(models.Model)
vote_to = models.ForeignKey(Participant, on_delete=models.CASCADE, related_name='vote_to')
voted_by = models.ForeignKey(Participant, on_delete=models.CASCADE, related_name='voted_by')
date_time = models.DateTimeField(auto_now=True)
Each vote by a participant would be a row in the Votes table or an object of type Vote.
Something like,
vote = Vote(vote_to=some_participant_object,
voted_by=someother_participant_object)
vote.save()
auto_now=True means the value will be added when the object gets created so you don't have to handle when the vote was cast.
You can then query the number of votes cast by a particular participant using the ORM.
A basic filter query should be enough. Get all the votes by a particular participant.
Something like,
# just as an idea here, the next lines might not be perfect
votes = Vote.objects.filter(voted_by__id=some_participant_id)
# or
votes = Vote.objects.filter(voted_by=some_participant_object)
# check the timestamp of the last vote and build logic accordingly
This way it'll be easier to write ORM queries to count the number of votes a particular participant has or the number of votes a particular participant has cast.
Suppose I have such models:
class Recipe (models.Model):
par_recipe = models.CharField(max_length=200)
class Line (models.Model):
par_machine = models.CharField(max_length=200)
class Measurements (models.Model):
par_value = models.IntegerField(default=0)
id_line = models.ForeignKey(Line)
id_recipe = models.ForeignKey(Recipe)
Do I understand correctly that in this way I have a 1: 1 relationship, and adding entries ids will be automatically created id_line,id_recipe.
I will add for example:
for row in ws.iter_rows(row_offset=1):
recipe =Recipe()
line = line()
measurements = Measurements()
recipe.par_recipe = row[1].value
line.par_machine = row[2].value
measurements.par_value = row[8].value
And the small question about measurements was conceived that all secondary keys should go to it, now it is implemented correctly?
It is not quite like that, you would have to tie them together:
for row in ws.iter_rows(row_offset=1):
recipe =Recipe.objects.create(par_recipe=row[1].value)
line = Line.objects.create(par_machine=row[2].value)
measurements = Measurements.objects.create(
par_value=row[8].value,
id_line=line,
id_recipe=recipe
)
None of this is db optimized, you could use transactions to optimize the db writes.
You could make it faster if there are a lot of rows by using transactions:
from django.db import transaction
with transaction.atomic():
for row in ws.iter_rows(row_offset=1):
recipe =Recipe.objects.create(par_recipe=row[1].value)
line = Line.objects.create(par_machine=row[2].value)
measurements = Measurements.objects.create(
par_value=row[8].value,
id_line=line,
id_recipe=recipe
)
This would create a transaction and write one instead of each time. But it will also fail the whole transaction on an error.
see Django Database Transactions
You could get more creative by counting the number of records and writing every 1000 records for example by:
from django.db import transaction
with transaction.atomic():
for idx, row in enumerate(ws.iter_rows(row_offset=1)):
recipe =Recipe.objects.create(par_recipe=row[1].value)
line = Line.objects.create(par_machine=row[2].value)
measurements = Measurements.objects.create(
par_value=row[8].value,
id_line=line,
id_recipe=recipe
)
# every 1000 records, commmit the transaction
if idx % 1000 == 0:
transaction.commit()
Do I understand correctly that in this way I have a 1: 1 relationship, and adding entries ids will be automatically created id_line,id_recipe.
The relations will not link to the previously constructed objects, that would also be quite unsafe since a small change to the code fragment, could result in a totally different way of linking elements together.
Furthermore a ForeignKey is a many-to-one relation: multiple Measurements objects can refer to the same Recipe object.
You need to do this manually, for example:
for row in ws.iter_rows(row_offset=1):
recipe = Recipe.objects.create(par_recipe=row[1].value)
line = Line.objects.create(par_machine=row[2].value)
measurements = Measurements.objects.create(
par_value=row[8].value,
id_line=line,
id_recipe=recipe
)
Note that a ForeignKey refers to the objects, not to the primary key value, so you probably want to rename your ForeignKeys. A model typically has a singular name, so Measurement instead of Measurements:
class Measurement(models.Model):
par_value = models.IntegerField(default=0)
line = models.ForeignKey(Line, on_delete=models.CASCADE)
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
I have different model. Choices of Multiselctfield of one model is dependent on another model.So , database has to be queried inside model.py While doing so, this causes problem in migration. (Table doesn't exist error)
class Invigilator(models.Model):
---
# this method queries Shift objects and Examroom
def get_invigilator_assignment_list ():
assignment = []
shifts = Shift.objects.all()
for shift in shifts:
rooms= ExamRoom.objects.all()
for room in rooms:
assign = str (shift.shiftName)+ " " +str (room.name)
assignment.append (assign)
return assignment
assignment_choice = []
assign = get_invigilator_assignment_list()
i = 0
for assignm in assign:
datatuple = (i,assignm)
assignment_choice.append(datatuple)
i= i+1
ASSIGNMENT_CHOICE = tuple(assignment_choice)
assignment =MultiSelectField (choices = ASSIGNMENT_CHOICE, blank = True, verbose_name="Assignments")
You cannot add dynamic choices because they are all stored in the migration files and table info. If Django lets you do that, this means that everytime someone adds a record to those 2 models, a new migration should be created and the db should be changed. You must approach this problem differently.
As far as I know django-smart-selects has a ChainedManyToMany field which can do the trick.
Here is an example from the repo.
from smart_selects.db_fields import ChainedManyToManyField
class Publication(models.Model):
name = models.CharField(max_length=255)
class Writer(models.Model):
name = models.CharField(max_length=255)
publications = models.ManyToManyField('Publication', blank=True, null=True)
class Book(models.Model):
publication = models.ForeignKey(Publication)
writer = ChainedManyToManyField(
Writer,
chained_field="publication",
chained_model_field="publications")
name = models.CharField(max_length=255)
This cannot be done in the model and doesn't make sense. It's like you're trying to create a column in a table with a certain fixed set of choices (what is MultiSelecField anyway?), but when someone later adds a new row in the Shift or ExamRoom table, the initial column choices have to change again.
You can
either make your assignment column a simple CharField and create the choices dynamically when creating the form
or you can try to model your relationships differently. For example, since it looks like assignment is a combination of Shift and ExamRoom, I would create a through relationship:
shifts = models.ManyToManyField(Shift, through=Assignment)
class Assignment(Model):
room = ForeignKey(ExamRoom)
shift = ForeignKey(Shift)
invigilator = ForeignKey(Invigilator)
When creating the relationship, you'd have to pick a Shift and a Room which would create the Assignment object. Then you can query things like invigilator.shifts.all() or invigilator.assignment_set.first().room.
I have three models:
Course
Assignment
Term
A course has a ManyToManyField which accesses Django's default User in a field called student, and a ForeignKey with term
An assignment has a ForeignKey with course
Here's the related models:
class Assignment(models.Model):
title = models.CharField(max_length=128, unique=True)
points = models.IntegerField(default=0, blank=True)
description = models.TextField(blank=True)
date_due = models.DateField(blank=True)
time_due = models.TimeField(blank=True)
course = models.ForeignKey(Course)
class Course(models.Model):
subject = models.CharField(max_length=3)
number = models.CharField(max_length=3)
section = models.CharField(max_length=3)
professor = models.ForeignKey("auth.User", limit_choices_to={'groups__name': "Faculty"}, related_name="faculty_profile")
term = models.ForeignKey(Term)
students = models.ManyToManyField("auth.User", limit_choices_to={'groups__name': "Student"}, related_name="student_profile")
When a user logs in to the page, I would like to show them something like this bootstrap collapse card where I can display each term and the corresponding classes with which the student is enrolled.
I am able to access all of the courses in which the student is enrolled, I'm just having difficulty with figuring out the query to select the terms. I've tried using 'select_related' with no luck although I may be using it incorrectly. So far I've got course_list = Course.objects.filter(students = request.user).select_related('term'). Is there a way to acquire all of the terms and their corresponding courses so that I can display them in the way I'd like? If not, should I be modeling my database in a different way?
https://docs.djangoproject.com/en/1.11/ref/models/querysets/#values
You could use values or values_list here to get the fields of the related model Term.
For example expanding on your current request:
To retrieve all the Terms' name and duration for the Courses in your queryset
Course.objects.filter(students = request.user).values('term__name', 'term__duration')
I am not sure what the fields are of your Term model, but you would replace name or duration with whichever you are trying to get at.
I think it helps you
terms = Terms.objects.filter(....) # terms
cources0 = terms[0].course_set.all() # courses for terms[0]
cources0 = terms[0].course_set.filter(students=request.user) # courses for terms[0] for user
I am currently working on developing a database and API system where users can create a portfolio which contains a list of coins. I am using Django and I searched everywhere but I kept seeing foreign keys but I'm not sure that's what I need in this situation.
I want two models, one for portfolios which a user will be able to query on, and another coin model which the user will be able to also query on. However in the portfolio there should be a list of coins. I know how to do this in Java using objects but not sure the method in Django.
Here is my model class:
from django.db import models
class Portfolio(models.Model):
name = models.CharField(max_length=250)
def __str__(self):
return self.name
class Coin(models.Model):
name = models.CharField(max_length=100)
symbol = models.CharField(max_length=5)
price = models.DecimalField(max_digits=20, decimal_places=9)
info = models.TextField()
website = models.TextField()
rank = models.IntegerField()
def __str__(self):
return self.name + " - " + self.symbol
Now I would ideally have something like coins = list of Coins model if I was using java to make the objects, but since this is for a database and in Django I'm not sure how I should link the two.
I've seen related objects but did not understand the explanations for my issue. How should I go about setting up these models? Thanks.
It sounds like you want to have a number of Portfolio objects each of which can have varying investments in Coin objects. In this case, you'd want to use a ManyToManyField:
class Portfolio(models.Model):
name = models.CharField(max_length=250)
coins = models.ManyToManyField(Coin)
The database would then store the two dimensional table of which Portfolio holds which coin.
However an alternate approach you could try is to create an object that separately represents the investment:
class Investment(models.Model):
portfolio = models.ForeignKey(Portfolio)
coin = models.ForeignKey(Coin)
bought = models.DateTimeField() # date the investment was made
sold = models.DateTimeField() # date the investment was sold
amount = models.DecimalField() # number of coins held
You could then add a property to Portfolio:
class Portfolio(models.Model):
name = models.CharField(max_length=250)
#property
def coins(self):
return Investment.objects.filter(portfolio=self)
In this way you can not only keep track of which portfolio holds which coins, buy also the entire historical positions too.