The right way to design a job model - python

I have a silly Job model in my app:
class Job(models.Model):
# working info
user = models.ForeignKey(User)
company = models.CharField(max_length=100, blank=True)
department = models.CharField(max_length=100, blank=True)
inaugural_date = models.DateField('inaugural date', blank=True)
resignation_date = models.DateField('resignation date', blank=True)
the above model is exactly what I have in my app and this model is used to let user get their college, nothing more.
It works, but I think there must be a better way to design this model, because suppose I want get all the users within the same company and same department in same period of time, its not that easy.
Please help me to reconstruct this model, any suggestion will be appreciated!

This should work:
User.objects.filter(
job_set__company__iexact="wwwww",
job_set__department__iexact="xxxxx",
job_set__inaugural_date__gt=yyyy,
job_set__resignation_date__lt=zzzz
)
It doesn't seem that complex to me, such query wouldn't be easy if you think in SQL terms, at least for me :)

Depends how much you predict on growing and what backend you use. For relation db (mysql/postgres etc) I would create a separate model for departments and companies and also create join tables for them in order to make my job easier later on.

Your model looks fine.
Even though Django model is not Anemic , I usually look it as pure data structure without too much logic. So I think
get all the users within the same company and same department in same period of time
is a logic which should not be a concern of your model, which also means, it should not influence your model design too much IMHO.
Model should be kept simple and thin, so that it can be adopted and adapted in/to different kinds of logic. If you try to make you model structure suitable to a specific logic, you will easily find yourself entangled with inflating models.
BTW, for complex query, you can fallback to Raw SQL

Related

AttributeError: 'Resume' object has no attribute 'prefetch_related'

I am trying to understand the use of prefetch_related and select_related for optimization. I learned somewhere in the blog that one of the where to use prefetch and select is, prefetch_related is used for reverse relation and select_related for the forward relation. In my case there is Resume model and Education Model. Education model has FK of resume with the related_name for reverse relation instead of writing additional _set when querying. I need to list all the education of an requested user with the requested user resume. I could do this without those optimization techniques as follow
education_instance = Resume.objects.get(applicant=request.user).educations.all()
When I tried to use the following instead, I get the error I stated in the title
education_instance = Resume.objects.filter(applicant=request.user).prefetch_related('educations')
Here is my model
class Resume(models.Model):
applicant = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100, blank=False, null=False, help_text="Full Name")
class Education(models.Model):
resume = models.ForeignKey(Resume, related_name='educations')
name = models.CharField(max_length=100, blank=False, null=False, help_text="Name of an institution")
Can anyone make me clear on select_related and prefetch_related with simple layman terms ? I could not understand the issue I am getting
From the Exception that you provided, you are trying to call .prefetch_related() on object Resume, not Resumes QuerySet.
So, make sure you run
Resume.objects.filter(applicant=request.user).prefetch_related('educations')
not
Resume.objects.get(applicant=request.user).prefetch_related('educations')
Actually you should use select_related in this case.
As far as i know prefetch_related is used for many to many relations and it makes two queries to retrieve objects while select_related is used for normal fk or one to one relations and it fetched all objects in one query using joins.
first of all go through this [document of prefetch_related][1]
[1]: https://docs.djangoproject.com/en/1.11/ref/models/querysets/#prefetch-related then you will find that you can not use it like this
you have to apply on Education modal
education_instance = Education.objects.filter(resume__applicant == request.user).prefetch_related('resume')
hope this will help you.

Ephemeral model instances for demo in Django 1.10

I need to dynamically create a series of models and relationships in a Postgres database for the purpose of demoing some features.
The issue is these models can't interfere with or be returned by queries in the normal functioning of the Django app. However they must have the full behavior set of the model and the ability to be returned by queries during the demo.
Using factories (we use Factory Boy primarily) is imperfect because the models can't be queried without being saved to the database at which point they interact with regular operation queries.
A second database is imperfect as well because the demo occurs during normal app operation and thus the "valid" model instances still need to be available.
Flagging the models as is_demo also won't work as there's a half dozen different types of models that need to be instantiated for the demo to work as intended.
I could clear the specific models that are created with a cron job or similar but they'd effect the database between creation and the scheduled job.
Running everything in a staging environment is acceptable, but the ideal answer allows me to run the demos on the production build.
Is there an accepted approach or useful library that I've missed?
A sample model that's involved in the demo:
class Transaction(models.Model):
amount = models.DecimalField(max_digits=8, decimal_places=2, db_index=True,
editable=False)
assigned_user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(db_index=True, editable=False)
description = models.CharField(max_length=255, null=True, blank=True)
is_declined = models.BooleanField(default=False)
is_pending = models.BooleanField(db_index=True)
fi_account = models.ForeignKey(
FinancialAccount, on_delete=models.CASCADE)
#property
def organization(self):
org = self.fi_account.organization
return org
We'd need to be able to query this model and use its .organization property successfully. Without having it effect other queries.
You could create a clone of your production environment (database and django app), then update your production codebase to include the demo features/fixes. This way you'd have a copy of the "valid" production models in addition to the new models you're demoing.
It sounds like you should have a "staging" environment that closely matches your production environment for situations just like this.
Edit
One option I just thought of would be to create a Demo model which keeps track of records created as part of a demo. This Demo model would be have a ForeignKey to your User model, so each User can create/destroy their own demo (or your view can create it).
This would let you delete any records created as part of a specified Demo object.
However, you'd have to make sure you add an exclude for all of your current queries/filters of the models you have now.
Honestly, I'm not sure if what you're asking for can be done without exhaustively modifying all of your Model filters to exclude whatever demo records you create.

DJANGO: How to query multiple tables, equal model without looping

I'm looking for a nice way to query(DJANGO) temporal data, which is stored in different tables, but share the same model. Here's an example data model:
class myModel(models.Model):
x = models.FloatField()
class Meta:
db_table = "24-01-2017"
Now, I could of course loop over the different days, changing _meta.db_table for every iteration, but there should be a way to do this in a single query in DJANGO. This doesn't seem to be it, as DJANGO develops this may be outdated and I don't see anything related in the documentation.
How to handle this neatly?
Thanks in advance!
Edit 1
Hm, probably I'm just looking for a way to perform a outer join... But I can't find any implementation for this.

Django - repeat ForeignKey vs. multi-level relationship

Assuming below (simplified) database schema:
class Site(models.Model):
...
class Business(models.Model):
site = models.ForeignKey(Site)
class Subscription(models.Model):
business = models.ForeignKey(Business)
class Invoice(models.Model):
subscription = models.ForeignKey(Subscription)
Is it better to include site = models.ForeignKey(Site) field in every site-related model (all above) and then ie.:
invoice = Invoice.objects.get(id=1)
invoice_site = invoice.site
or use multi-level relation like this:
invoice = Invoice.objects.get(id=1)
invoice_site = invoice.subscription.business.site
I have such situations in many places of my code and always wonder which option is better. First is cleaner, do not break "DRY" rules and prevents inconsistency but the other allows to gain performance and optimization improvements through preventing complicated database joins.
Of course I assume that site is always consistent in above models, so there is no possibility to have Business with site A and Invoice with site B.
Well, relational database design has no place for DRY, it's all about relations. You need to think logically what the relationship structure of your application should be.
I couldn't speak definitively because I'm not in your shoes to understand the requirement 100%, but I'm almost certain that site shouldn't be directly associated with Invoice. Invoice is related to your business subscriptions and shouldn't depend on/know which site does the business happen. Same thing for Subscription model. A simple trouble if you have site in Invoice is that you are duplicating the relationship, and an Invoice couldn't exist if there's no such site yet.
I suggest you check out some basics of relational database design and gain a better understanding of the concept of normalization. It would help you design a better schema without causing trouble with relations.

How to make a base class when childs can't inherit?

I have a fairly simple model in Django, let's say Book:
class Book(models.Model):
name = models.CharField(max_length=255, default="")
description = models.TextField(null=True, blank=True)
creation_date = models.DateTimeField()
Because the structure and data basically comes from an external API, I have contained it in its own app and I rather not want to modify it.
Now I want to add another source of different books to the project and I'm not really sure what the best solution is here.
Let's say the second model is:
class NextBook(models.Model):
title = models.CharField(max_length=255, default="")
long_description = models.TextField(null=True, blank=True)
created = models.DateTimeField()
So the basic fields are there, but have different names. To get the two together, I can probably use another model with a GenericForeignKey:
class BaseBook(models.Model):
book_type = models.ForeignKey(ContentType)
book_id = models.PositiveIntegerField()
book_object = generic.GenericForeignKey('book_type', 'book_id')
But then I cannot query for all the book as e.g. BaseBook.objects.all().order_by('created') wouldn't work. Surely, I could go on and duplicate a datetime field in the base model and then the title and so on, but I think that would be the wrong direction. Also inheritance seems not a choice if I don't want to touch the specific models.
I am looking for some design pattern or something that let's me efficiently 'plug in' more providers and query for all objects, while not making a huge mess of model structure and database queries.
There’s a fundamental contradiction in your question. Do you assume that, for a given book, the created reported by different providers will be the same?
If yes, why can’t you make a created field on your BaseBook and order by that? You can then drop the creation_date from your Book (or just ignore it, if you don’t want to touch it).
If not, how do you want to order books (not provider entries) by created in the first place?
Also, what you’re trying to do sounds like a good case for a free-schema database like MongoDB. There, you can embed provider entries directly in your book documents, then order by something like “created from the first provider entry for the book”. Thus, you maintain self-contained provider documents without denormalization. You still need created to mean the same thing for all providers, though.

Categories

Resources