I have the following model:
class Trip(models.Model):
driver = models.ForeignKey(User)
trip_cost = models.IntegerField(blank=True, null=True)
passenger = models.CharField(max_length=50, blank=True, null=True)
shared_cost = models.IntegerField(default=0, blank=True, null=True)
Each Trip can have a driver alone, or a driver with several passenger. For each passenger the driver can set the percentage of the trip_cost each passenger is going to pay.
What I need is to have:
the field passenger to be listing all Users
several passenger + shared_cost for each Trip.
I guess I should use Many-to-many but I cannot make it work. Also when I try to set the passenger to models.ForeignKey(User), I get an error.
Any help or direction highly appreciated.
Use related_name when refer to same models using 2 fields.
class Trip(models.Model):
driver = models.ForeignKey(User,on_delete=models.CASCADE, related_name='driver')
trip_cost = models.IntegerField(blank=True, null=True)
passenger = models.ForeignKey(User,on_delete=models.CASCADE, related_name='passenger')
shared_cost = models.IntegerField(default=0, blank=True, null=True)
Related
I try to filter materialized postgres views in Django views.py. The database and the views were created with postgres. I can filter views which represent one to many relationships and I can access views with get (queryset) which represent many to many relationships. But I cannot filter those views which represent many to many relationships. Models were created with inspectdb. It's a postgis legacy database.
How do I have to filter these views?
models.py
fid = models.AutoField(primary_key=True)
id_dokument = models.IntegerField(blank=True, null=True)
dokument = models.CharField(max_length=50, blank=True, null=True)
datei = models.CharField(max_length=100, blank=True, null=True)
beschreibung = models.CharField(max_length=1024, blank=True, null=True)
datum = models.DateField(blank=True, null=True)
person = models.CharField(max_length=50, blank=True, null=True)
dokumenttyp = models.CharField(max_length=30, blank=True, null=True)
id_objekt = models.IntegerField(blank=True, null=True)
objekt = models.CharField(max_length=50, blank=True, null=True)
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'objekt_dokumente_rel'
views.py
dokumente = ObjektDokumenteRel.objects.using('db').filter(id_objekt=fid)
If replacing filter with get I receive one object (as expected).
Adding __exact to id_objekt dokumente = ObjektDokumenteRel.objects.using('db').filter(id_objekt__exact=fid) resolves the problem. Has anyone an idea why?
I am creating a Django web based application for freelancers ,that they would be paid for number of hours they have worked on a project and also a weekly report is to be generated for weekly work and for that i need to work with time stamps so how do i implement it?
I want to create a button of start timer and stop timer, which records the time stamps of start timer and end timer?
I have a User model which is extended to Freelancer and person who hires Freelancer. How do i implement this?
Where do i edit the model of time stamps?
I have this model
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
is_freelancer = models.BooleanField('Freelancer status', default=False)
is_hirer = models.BooleanField('Hirer status', default=False)
class Freelancer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
hourly_rate = models.PositiveIntegerField(default=10)
education = models.TextField(default='asia')
professional_bio = models.TextField(blank=True, null=True)
professional_title = models.TextField(blank=True, null=True)
location = models.CharField(max_length=10, blank=True, null=True)
Address = models.CharField(max_length=100, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
postal_code = models.PositiveIntegerField(blank=True, null=True)
country = models.CharField(max_length=100, blank=True, null=True)
class Hirer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
hourly_budget = models.PositiveIntegerField(blank=True, null=True)
project_title = models.CharField(max_length=100, default='hi')
project_description = models.TextField(blank=True, null=True)
job_category = models.CharField(max_length=100)
professional_bio = models.TextField(blank=True, null=True)
professional_title = models.TextField(blank=True, null=True)
location = models.CharField(max_length=10, blank=True, null=True)
Address = models.CharField(max_length=100, blank=True, null=True)
city = models.CharField(max_length=100, blank=True, null=True)
postal_code = models.PositiveIntegerField(blank=True, null=True)
country = models.CharField(max_length=100, blank=True, null=True)
This question is a bit broad, and I'm not really sure what it has to do with timestamps. But you might think about an "TimeWorked" model with foreign keys to both hirer and freelancer:
class TimeWorked(models.Model):
hirer = models.ForeignKey('Hirer', on_delete=models.CASCADE)
freelancer = models.ForeignKey('Freelancer', on_delete=models.CASCADE)
rate = models.IntegerField()
start_time = models.DateTimeField(auto_now_add=True)
end_time = models.DateTimeField(null=True, blank=True)
so you can create an instance of this class at the start of a block of time, then at the end fill in the end_time; then you can easily query the total amount of time worked for a job, and calculate the total to bill.
(Note you might want to rethink your models a bit, especially separating the project details from the hirer, otherwise each hirer can only ever create a single project.)
In my database I have user objects with two many to many fields (messages and following) on them that both contain a many to many field related to another object Topic.
class User():
messages = ManyToManyField('Message', related_name='users', blank=True, null=True)
following = ForeignKey('Following', related_name='users', blank=True, null=True)
class Message():
date = DateField(blank=True, null=True)
content = TextField(blank=True, null=True)
topics = ManyToManyField('Topic', related_name='messages', blank=True, null=True)
class Following():
name = CharField(max_length=255, blank=True, null=True)
description = CharField(max_length=255, blank=True, null=True)
topics = ManyToManyField('Topic', related_name='following', blank=True, null=True)
class Topic():
name = CharField(max_length=255, blank=True, null=True)
source = CharField(max_length=255, blank=True, null=True)
I want to filter for all "users" who have "messages" attached to them that do not contain all of the topics attached to the "following" objects on the user.
Right now I am using a loop to accomplish this:
users = set()
for user in User.objects.filter(messages__isnull=False, following__isnull=False).iterator():
if not set(user.following.values_list('topics', flat=True))
).issubset(set(user.messages.values_list('topics', flat=True)):
users.add(user.pk)
Is there a way to accomplish the same thing with a single query?
---- EDIT ----
What I have is this:
User.objects.filter(following__isnull=False
).annotate(following_count=Count('following__topics', distinct=True)
).filter(following__topics__exact=F('message__topics')
).annotate(missing_topics=ExpressionWrapper(
F('following_count') - Count('message__topics', distinct=True),
IntegerField())
).filter(missing_topics__gt=0)
If there is a better way to do this or there are reasons why I should most definitely not do it this way, what are they?
---- EDIT ----
This question helped me to understand and use HÃ¥ken Lid's answer
This is my new model and my new query:
class User():
messages = ManyToManyField('Message', related_name='users', blank=True, null=True)
following = ManyToManyField('Topic', through='Following', related_name='users', blank=True, null=True)
class Message():
date = DateField(blank=True, null=True)
content = TextField(blank=True, null=True)
topics = ManyToManyField('Topic', related_name='messages', blank=True, null=True)
class Following():
name = CharField(max_length=255, blank=True, null=True)
description = CharField(max_length=255, blank=True, null=True)
user = ForeignKey('User', related_name='following', blank=True, null=True)
topic = ForeignKey('Topic', related_name='following', blank=True, null=True)
class Topic():
name = CharField(max_length=255, blank=True, null=True)
source = CharField(max_length=255, blank=True, null=True)
User.objects.filter(~Q(messages__topics__in=F('following'))
).values('id').annotate(missing_topics=Count('following__topics', distinct=True))
This should be possible using a subquery.
First, make sure Following.topics uses a different related name than Messages.topics.
class Following(models.Model):
topics = ManyToManyField('Topic', related_name='following')
Then it should be possible to create a subquery. Something like this:
from django.db.models import OuterRef, Subquery
user_following_topic = Topic.objects.filter(following__users=OuterRef('pk'))
User.objects.exclude(messages__topics__in=Subquery(user_following_topics.values('pk')))
This might not work and give you your expected output exactly as written, but I think the principle should work for your case as well.
On the other hand, I don't really understand your database structure. It seems you use m2m relations where foreign keys could be more appropriate and simpler. The more complicated your relations are, the harder it is to create this kind of advanced query. And queries with lots of database joins can be very slow, since they might have to process huge amounts of data, compared to simple queries.
For example, instead of using m2m realitions, Following would make more sense to me like so:
class Following():
topic = ForeignKey('Topic', on_delete=models.CASCADE)
user = ForeignKey('User', on_delete=models.CASCADE)
client = models.CharField(max_length=255, blank=True, null=True)
duration = fields.DateRangeField(blank=False, null=False)
So basically a "through" model, as explained in the django docs on model relationships where there's a similar example.
#models.py
class Orders(models.Model):
orderid = models.IntegerField(db_column='orderID', primary_key=True)
createdate = models.DateField(db_column='createDate', blank=True, null=True)
pickupdate = models.DateField(db_column='pickupDate', blank=True, null=True)
returndate = models.DateField(db_column='returnDate', blank=True, null=True)
pickupstore = models.ForeignKey(Branch, models.DO_NOTHING, db_column='pickupStore', blank=True, null=True,related_name = 'pickupstore')
returnstore = models.ForeignKey(Branch, models.DO_NOTHING, db_column='returnStore', blank=True, null=True,related_name = 'returnstore')
rentedvehicle = models.ForeignKey('Vehicles', models.DO_NOTHING, db_column='rentedVehicle', blank=True, null=True)
customer = models.ForeignKey(Customer, models.DO_NOTHING, db_column='customer', blank=True, null=True)
class Vehicles(models.Model):
vehicleid = models.IntegerField(db_column='vehicleID', primary_key=True)
make = models.CharField(max_length=45, blank=True, null=True)
model = models.CharField(max_length=45, blank=True, null=True)
series = models.CharField(max_length=45, blank=True, null=True)
Orders model have foreign key rentedvehicle which refers to Vehicles models
I have filtered the data based on the pickupstore state, e.g. The list of vehicles that are picked up from store in a particular state
Vehicles.objects.filter(orders__pickupstore__state = request.POST['state'])
I want to be able to filter the filtered data above so that I can get a list of vehicles that are picked up from store in a particular state WITH its latest entry in Orders models has returnstore__state == a particular state
So basically, I want to achieve this:
Vehicles.objects.filter(orders__pickupstore__state = request.POST['state']).filter(the latest entry returnstore state =request.POST['state'])
Many possible solutions. Optimal depends on your Django version (1.11 or higher?). Here's one possible solution:
from django.db.models import Max, F
Vehicles.objects.filter(orders__pickupstore__state = request.POST['state']).annotate(max_date=Max('orders__returndate')).filter(orders__return_date=F('max_date')).filter(orders__state = request.POST['state'])
What's happening here is that we're identifying the most recent return date, then filtering the orders to only include the most recent, then filtering the Vehicles on the state of that latest order.
I've little problem with django models. I'm trying to create a game statistics service, but can't figure out how could I pick players from each team as a starting roster (doesn't contain all of the team players) of the game. Picking should work so that home and visitor has separated player lists. And then it should be possible to create eg Goal object where I could pick player as scorer only from the starting roster. I've already tried to put home and visitor players as ManyToManyField in the Game model, but it won't work. It needs some filtering at least.
class Game(models.Model):
series = models.ForeignKey(Series, related_name="game_series")
date = models.DateTimeField(default=None, blank=True, null=True)
home = models.ForeignKey(Team, related_name="game_home")
visitor = models.ForeignKey(Team, related_name="game_visitor")
class Goal(models.Model):
game = models.ForeignKey(Game, related_name="goal_game")
minutes = models.PositiveIntegerField(default=None, blank=True, null=True)
seconds = models.PositiveIntegerField(default=None, blank=True, null=True)
scorer = models.ForeignKey(Player, related_name="goal_scorer")
assist = models.ForeignKey(Player, related_name="goal_assist")
class Save(models.Model):
game = models.ForeignKey(Game, related_name="save_game")
player = models.ForeignKey(Player, related_name="save_player")
count = models.PositiveIntegerField(default=None, blank=True, null=True)
The question is: how should I modify models to achieve the desired result? Note: I'm using admin views for data input, so the proposed resolution should work from there.
EDIT: There is also Player model which I forgot to explain earlier. So, both of teams has already defined list of players where to pick roster for the game.
class Player(models.Model):
team = models.ForeignKey(Team, on_delete=models.PROTECT, related_name="player_team")
firstname = models.CharField(max_length=200, default=None, blank=True, null=True)
lastname = models.CharField(max_length=200, default=None, blank=True, null=True)
number = models.IntegerField(default=None, blank=True, null=True)
description = models.TextField(default=None, blank=True, null=True)