Django: Make a query inside a class - django

I want to make a query inside a class of my model. I have the following model where a contract is made when a person has a project.
class Person(models.Model):
name = models.CharField(max_length=32)
surname = models.CharField(max_length=32)
address = models.CharField(max_length=32)
is_doctor = models.NullBooleanField(blank=True, verbose_name=_(u"Phd?")
class Project(models.Model):
name = models.CharField(max_length=32, verbose_name=_(u"Name"))
principal_researcher = models.ForeignKey(Person, blank = True, verbose_name=_(u"Researcher associated with the project"))
class Contract(models.Model):
person = models.ForeignKey(Person) #person hired
project = models.ForeignKey(Project, blank = True, null = True) #related project
type_contract = models.CharField(max_length = 9, blank = True, verbose_name = _(u"Type of contract(Full time/grant/Partial time...)"))
starting_date = models.DateField(blank = True, null = True)
ending_date = models.DateField(blank = True, null = True)
term = models.CharField(max_length = 120, blank = True)
I want to create a class where the user will be able to make this query:
Tell me all the people, without Phd, with full time contract with a contract among two dates.
So the user only has to enter two dates to get the query.
(All of this from the Admin interface)

I don't know what you mean by "inside a class".
You can make your query like this:
Person.objects.filter(
is_doctor=False,
contract__type_contract='full',
contract__starting_date__gte=start_date,
contract__ending_date__lte=end_date
)
If you want to define a method to execute this query, that is normally done inside a model manager:
class PersonManager(models.Manager):
def full_time_no_doctors_contract_between(self, start_date, end_date):
return self.filter(...)
class Person(models.Model):
...
objects = PersonManager()
and now you can do:
Person.objects.full_time_no_doctors_contract_between(start_date, end_date)

Related

How to get exact values of the foreignkeys in django admin

class Mio_terminal(models.Model):
terminal = models.CharField(max_length = 50)
gate = models.CharField(max_length = 50)
gate_status = models.CharField(max_length = 50, default = 'open') #open, occupied, under_maintenance
class Meta:
unique_together = [['terminal', 'gate']]
class Mio_flight_schedule(models.Model):
fact_guid = models.CharField(max_length=64, primary_key=True)
airline_flight_key = models.ForeignKey(Mio_airline, related_name = 'flight_key', on_delete = models.CASCADE)
source = models.CharField(max_length = 100)
destination = models.CharField(max_length = 100)
arrival_departure = models.CharField(max_length=12)
time = models.DateTimeField()
gate_code = models.ForeignKey(Mio_terminal, related_name = 'terminal_gate', null = True, on_delete = models.SET_NULL)
baggage_carousel = models.CharField(max_length = 100)
remarks = models.CharField(max_length = 100)
terminal_code = models.ForeignKey(Mio_terminal, related_name = 'airport_terminal', null = True, on_delete = models.SET_NULL)
These are models for terminal and flight schedules.
enter image description here
enter image description here
I want to have a terminal name and gate code instead of the object ...
I know we can get this by using the str method in models....but we get only a single value for this...not more than one
I want to use the terminal as a foreign_key for terminal_code in the flight_schedule model and the gate as a gate_code.I am getting terminal_code _gate code as a string ...but it's not reflecting as separate entities...I don't want the combined string.....I want when I click on the terminal ...only the terminal dropdown should display..and the same for the gate code
please let me know how should I deal with this.
You can change the display name of models in django admin interface by using def __str__(self).
So for in your code add this function after the Mio_terminal class :
class Mio_terminal(models.Model):
terminal = models.CharField(max_length = 50)
gate = models.CharField(max_length = 50)
gate_status = models.CharField(max_length = 50, default = 'open') #open, occupied, under_maintenance
class Meta:
unique_together = [['terminal', 'gate']]
# add this
def __str__(self):
return str(self.terminal+' '+self.gate)

Django Testing IntegrityError: duplicate key value violates unique constraint DETAIL: Key (project_id)=(1023044) already exists

I have not been able to resolve this IntegrityError issue in my Django's unittest. Here are my models:
class UserProfile(models.Model):
''' UserProfile to separate authentication and profile '''
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, null = True, blank = True)
# Note: first name and last name is in the custom User model
first_name = models.CharField(max_length = 20, blank = True, null = True)
last_name = models.CharField(max_length = 30, blank = True, null = True)
address = models.CharField(max_length = 100, null=True, blank = True)
address_city = models.CharField(max_length = 30, null = True, blank = True)
metropolitan = models.CharField(max_length = 30, null = True, blank = False)
class Municipality(models.Model):
name = models.CharField(max_length = 50)
abb = models.CharField(max_length = 5)
date_created = models.DateTimeField(auto_now_add = True)
date_modified = models.DateTimeField(auto_now = True)
userprofile = models.ForeignKey('user_profile.UserProfile', blank = False, null = False, related_name = 'userprofile_municipalities', on_delete = models.CASCADE)
class Project(models.Model):
name = models.CharField(max_length = 50)
logo = models.ImageField(null=True, blank = True, width_field = 'logo_width', height_field = 'logo_height')
logo_height = models.IntegerField(default = 40)
logo_width = models.IntegerField(default = 40)
date_created = models.DateTimeField(auto_now_add = True )
date_modified = models.DateTimeField(auto_now = True )
# RELATIONSHIPS:
user_profiles = models.ManyToManyField('user_profile.UserProfile', through = 'ProjectAssociation', through_fields = ('project', 'user_profile' ), blank = True, related_name = 'user_projects')
address = models.OneToOneField(Address, on_delete = models.PROTECT, null = True, blank = True)
municipality = models.ForeignKey('development.Municipality', related_name = 'municipality_projects', null = False, blank = False)
class Job(models.Model):
project = models.OneToOneField('project_profile.Project', blank = False, on_delete = models.CASCADE, related_name = 'job')
...
date_modified = models.DateTimeField(auto_now_add = True)
date_created = models.DateTimeField(auto_now = True)
class Invoice(models.Model):
PO = models.CharField(max_length = 50, blank = False, null = False) # e.g. Mixed Use Residential Commercial Rental Invoice
invoice_type = models.CharField(max_length = 40)
date_created = models.DateTimeField(auto_now = True)
date_modified = models.DateTimeField(auto_now_add = True)
job = models.ForeignKey(DevelopmentProject, related_name = 'job_invoices', blank = True, null = True, on_delete = models.CASCADE)
Invoice_creator = models.ForeignKey('user_profile.UserProfile', related_name = 'created_invoices', blank = True, null = True, on_delete = models.SET_NULL) # ModelForm to enforce If the Invoice creator's account is closed, the corresponding Invoices to be preserved
Invoice_reviewer = models.ForeignKey('user_profile.UserProfile', related_name = 'reviewed_invoices', blank = True, null = True , on_delete = models.SET_NULL ) # The reviewer is not necessary, but
...
In my unittest, I am getting integrity error message even when I try to explicitly assign unique id to the created instance:
class UpdateinvoiceTestCase(TestCase):
''' Unit Test for Updateinvoice View '''
def setUp(self):
self.factory = RequestFactory()
# Create the dependencies
self.userprofile = mommy.make('user_profile.UserProfile')
print ('User profile: ', self.userprofile, ' - userprofile id: ', self.userprofile.id )
self.municipality = mommy.make('development.municipality', userprofile = self.userprofile, _quantity=1)
self.project = mommy.make('project_profile.Project', municipality = self.municipality[0], _quantity=2)
self.job = mommy.make('development.Job', project = self.project[0] )
# Create invoice
self.invoice = mommy.make('development.invoice', job = self.job)
# Passing the pk to create the url
the_uri = reverse('development:update_invoice', args=(self.invoice.pk,))
the_url = 'http://localhost:8000' + reverse('development:update_invoice', args=(self.invoice.pk,))
# Creating a client:
self.response = self.client.get(the_url, follow=True)
def test_url(self):
''' Ensure that the url works '''
self.assertEqual(self.response.status_code, 200)
I have made sure only one test is run using so there is no sharing of the data between different testcases that would throw Django off:
python manage.py test project.tests.test_views.UpdateViewTestCase
I get the the following error message:
IntegrityError: duplicate key value violates unique constraint "development_developmentproject_project_id_key"
DETAIL: Key (project_id)=(1) already exists
I also tried using mommy.make to create project, but I got the same error message. I also tried to specifically assign non-existent ids to the Project creation line, but could not convince Django to stop complaining.
So, Project is being created twice, but I cannot figure out why and where. Any help is much appreciated!
It turned out that I've used signals which created an instance already and I was creating the same instance in my setUpTestData again. The solution was to avoid creating a duplicate instance or simply use get_or_create instead of create or mommy.make

Fetch data from multiple tables in django views

In Django views, I want to fetch all details(Workeraccount.location,Workeravail.date, Workerprofile.*) for any particular wid=1.
SQL Query:
select * from Workeraccount,Workeravail,Workerprofile where Workerprofile.wid=1 and Workerprofile.wid=Workeravail.wid and Workeraccount.wid=Workerprofile.wid;
The corresponding models are as follows:
class Workeraccount(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid', unique=True)
location = models.ForeignKey(Location, db_column='location')
class Meta:
managed = False
db_table = 'workerAccount'
class Workeravail(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid')
date = models.DateField()
class Meta:
managed = False
db_table = 'workerAvail'
class Workerprofile(models.Model):
wid = models.SmallIntegerField(primary_key=True)
fname = models.CharField(max_length=30)
mname = models.CharField(max_length=30, blank=True, null=True)
lname = models.CharField(max_length=30)
gender = models.CharField(max_length=1)
age = models.IntegerField()
class Meta:
managed = False
db_table = 'workerProfile'`
You can do this:
workprofile = Workerprofile.objects.filter(id=1).first()
all_worker_avails = workprofile.workeravail_set.all()
all_workeraccounts = workprofile.workeraccount_set.all()
As Workeraccount and Workeravail are related through Workerprofile, you can get one queryset easily - you will need two separate ones.
You can also do the following:
all_worker_avails = Workeravail.objects.filter(wid=workprofile)
...
Here is how you can do it with only one database call:
workprofile = Workerprofile.objects.get(pk=1)
.select_related('workeravail_set', 'workerprofile_set')
This will fetch all the data for you at once, which can then be used with:
workprofile.workerprofile_set.location #Gets the Workeraccount.location
workprofile.workeravail_set.date #Gets the Workeravail.date
workprofile.fname #Example of Workerprofile.*
As an aside, if you want a shorter way to reference the foreign objects than the "*_set" method, you can set a related_name like
class Workeraccount(models.Model):
wid = models.ForeignKey('Workerprofile', db_column='wid', unique=True, related_name='waccount')
...
And then replace workeraccount_set with waccount

Django foreign key is not set and hence unable to save form

I have a simple foreign key relationship between two tables. I am able to save the parent, but am unable to save the child which has a foreign key to the parent. This is what my models look like:
class Product(models.Model):
month_choices = tuple((m,m) for m in calendar.month_abbr[1:])
year_choices = tuple((str(n), str(n)) for n in range(2004, datetime.now().year +2 ))
id = models.AutoField(primary_key = True)
title = models.CharField(max_length = 1024)
product_type = models.ForeignKey(ProductType)
month = models.CharField(max_length =3, choices=month_choices)
year = models.CharField(choices=year_choices, max_length = 4)
project = models.CharField(max_length = 15, null = True, blank = True)
url = models.URLField(null = True, blank = True)
export_to_xsede = models.BooleanField()
#def __str__(self):
# return str(self.id)
class Meta:
db_table = "product"
class ProductResource(models.Model):
CHOICES = (('A','A'),('B','B'),('C','C'),('D','D'),('E','E'))
id = models.AutoField(primary_key = True)
product = models.ForeignKey(Product)
resource = models.CharField(choices=CHOICES, max_length = 15)
And my views:
class PublicationForm(forms.ModelForm):
title = forms.CharField(widget=forms.TextInput(attrs={'size':'70'}),required=False)
url = forms.CharField(widget=forms.TextInput(attrs={'size':'70'}),required=False)
class Meta:
model = Product
class ResourceForm(forms.ModelForm):
resource = forms.MultipleChoiceField(choices=ProductResource.CHOICES, widget = forms.CheckboxSelectMultiple)
class Meta:
model = ProductResource
I save the parent:
saved_publication = publications_form.save()
but am unable to save the resource form:
resource_form = ResourceForm(request.POST, instance = saved_publication)
resource_form.product = saved_publication
resource_form.save()
When I print resource_form.errors, I get:
<ul class="errorlist"><li>product<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
I have no idea why the foreign key is not getting set in this case.
I'm assuming you do not want to display the product field on the form, so you should exclude it from the form so the validation will pass:
class ResourceForm(forms.ModelForm):
resource = forms.MultipleChoiceField(choices=ProductResource.CHOICES, widget = forms.CheckboxSelectMultiple)
class Meta:
model = ProductResource
exclude = ['product']
Then in the view, just set the product manually after calling is_valid(). Just be sure to pass commit=False on the form.save() so that it will not actually save to the database until after you set the product. For example
...
saved_publication = publications_form.save()
resource_form = ResourceForm(request.POST)
if resource_form.is_valid():
resource = resource_form.save(commit=False)
resource.product = saved_publication
resource.save()

Django Model Won't Validate or Not Installed

Can you see why I am getting this model validation error?
I have the table in MySQL called 'paypal_transactions' with records.
I'm trying to copy this project over to another computer with the existing database.
Error Message:
One or more models did not validate: store.purchase: 'paypal_transaction' has a
relation with model <class 'f3.paypal.models.PaypalPaymentTransactions'>, which
has either not been installed or is abstract.
paypal/models.py
class PaypalPaymentTransactions(models.Model):
class Meta:
db_table = 'paypal_transactions'
payment_id = models.CharField(max_length = 50)
payer = models.CharField(max_length = 25)
amount = models.DecimalField(decimal_places = 2, max_digits = 8,
blank = True, default = "0.00")
currency = models.CharField(max_length = 10)
store/models.py
from f3.paypal.models import PaypalPaymentTransactions
class Purchase(models.Model):
user = models.ForeignKey(User, related_name = 'purchase_user')
product = models.ForeignKey(Design)
quantity = models.IntegerField()
paypal_transaction = models.ForeignKey(
PaypalPaymentTransactions,
default = None,
null = True,
blank = True)
This error occurs probably because of a dependency issue:
Try use the ForeignKey like this:
class Purchase(models.Model):
user = models.ForeignKey(User, related_name = 'purchase_user')
product = models.ForeignKey(Design)
quantity = models.IntegerField()
paypal_transaction = models.ForeignKey(
'f3.paypal.PaypalPaymentTransactions',
default = None,
null = True,
blank = True)