I have Patient model which has many to many relation with ICF model. ICF model has many to one field to Unite model. In Unite model I have Unite names. I want to reach Unite names that are assigned to Patient with relations. I try to reach Unite names for each Patient. If it is more than one I cannot list them for that person. Here are my codes.
This is my patient model.
class Patient (models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
lastname = models.CharField(max_length=255, default="doe")
data = models.JSONField()
Intensivecare_form = models.ManyToManyField(Intensivecare_Form)
isDeleted = models.BooleanField(default=False)
This is my ICF model.
class Intensivecare_Form (models.Model):
id = models.AutoField(primary_key=True)
hospitals_id = models.ForeignKey(Hospital, on_delete=models.CASCADE)
formname = models.CharField(max_length=128)
data = models.JSONField()
unites_id = models.ForeignKey(Unite, on_delete=models.CASCADE)
At last, This is my Unite model
class Unite (models.Model):
id = models.AutoField(primary_key=True)
unitename = models.CharField(max_length=128)
In my views.py file I have a function as below
def listPatients(request):
Patients = Patient.objects.all()
output = []
for patient in Patients:
unitename = []
icfinfo = serializers.serialize('json', patient.Intensivecare_form.all())
jsonicfinfo = json.loads(icfinfo)
unitename.append(jsonicfinfo)
output.append({'id': patient.id,
'fname': patient.name,
'lname': patient.lastname,
'data': patient.data,
'unitename': unitename,
})
return JsonResponse(output, safe=False)
This is what output looks like. I need to reach formname in unitename
0-> id, fname..., unitename-> 0 -> fields -> unitename
It seems your ICForm is only pointing at one Unite object.
Maybe try this to get all ICForm's in the query.
Instead of
unitename = []
icfinfo = serializers.serialize('json', patient.Intensivecare_form.all())
jsonicfinfo = json.loads(icfinfo)
unitename.append(jsonicfinfo)
Try renaming Intensivecare_form model rename unites_id to unites -- django knows to link on the id automatically and calling it unites_id could cause naming conflicts
Intensivecare_Form(models.Model):
unites = models.ForeignKey(Unites, on_delete=models.CASCADE)
And to get all unites names just get it in one query
unite_names = list(patient.Intensivecare_form.all().values_list('unites__unitename', flat=True))
That should do it for you! Best of luck!
Related
EDIT 22/01/2021
Thanks for advices in models naming.
Here is diagram of my database: https://dbdiagram.io/d/5fd0815c9a6c525a03ba5f6f?
As you can see in this diagram, I have simplyed as Customers_Orders is in fact a ternary relationship with models comments. I decided to use an 'declared' throught models for this ternary relationship
Do I realy need to add a ManyToMany fields in Orders?
I have a look at Django's doc example with person, group and membership (https://docs.djangoproject.com/fr/3.1/topics/db/models/) and a manytomany fiels is added only in Group model, not in Person model
I have 2 models (Customers and Orders) with a declared throught models (Customers_Orders) to manage manytomany relationship.
But I did'nt understand how to query to have :
for one Customer, all its orders: How many orders were made by each customer
for one Order, all its customers: How many customers were associated for each order
I have understood, I should do:
c = Customers.objects.get(customer_id=1)
c.CustomersOrders.all() but it failled AttributeError: 'Customers' object has no attribute 'CustomersOrdersComments'
class Customers(SafeDeleteModel):
customer_id = models.AutoField("Customer id", primary_key = True)
orders = models.ManyToManyField(Orders, through = Customers_Orders, related_name = "CustomersOrders")
created_at = models.DateTimeField("Date created", auto_now_add = True)
class Orders(SafeDeleteModel):
order_id = models.AutoField("Order id", primary_key = True)
created_at = models.DateTimeField("Date created", auto_now_add = True)
class Customers_Orders(SafeDeleteModel):
order = models.ForeignKey("Orders", on_delete = models.CASCADE)
customer = models.ForeignKey("Customers", on_delete = models.CASCADE)
You can do this - Given these models:
class Customer(models.Model):
name = models.CharField(max_length=30, default=None, blank=True, null=True)
orders = models.ManyToManyField("Order", through="CustomerOrder", related_name="orders")
created_at = models.DateTimeField(auto_now_add=True)
class Order(models.Model):
created_at = models.DateTimeField(auto_now_add = True)
customers = models.ManyToManyField(Customer, through="CustomerOrder", related_name="customers")
class CustomerOrder(models.Model):
order = models.ForeignKey("Order", on_delete = models.CASCADE)
customer = models.ForeignKey("Customer", on_delete = models.CASCADE)
customer = Customer.objects.first()
# Get count of their orders
customer_orders_count = customer.orders.all().count()
order = Order.objects.first()
# Get count of order's customers
order_customers_count = order.customers.all().count()
The docs explains this quite well:
https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/
In your case, that would be something like:
customer = Customers.objects.get(customer_id=1) # Fetch a specific customer from DB
customer_orders = customer.orders.all() # Return a QuerySet of all the orders related to a given `customer`
c.CustomersOrders.all() can't work, because CustomersOrders is the class name of your through model, and your Customers model does not have any CustomersOrders field.
I'm trying the get the records from the Student table, condition is that the student's primary key do not exist in the From table.(From is used as a relation) table.
Relation is "student from department"
Model:
class Student(models.Model):
name = models.CharField(max_length=20)
password = models.CharField(max_length=30)
phone_no = PhoneNumberField(null=False, blank=False, unique=True)
email = models.EmailField()
pic_location = models.FileField()
username = models.CharField(max_length=30)
class From(models.Model):
s = models.ForeignKey(Student, on_delete=models.PROTECT)
d = models.ForeignKey(Department,on_delete=models.PROTECT)
class Department(models.Model):
name = models.CharField(max_length=20)
password = models.CharField(max_length=30)
phone_no = PhoneNumberField(null=False, blank=False, unique=True)
email = models.EmailField()
I'm trying to get those records in the list view. And please review whether the way i'm retrieving session variable is good to go in such case??
class PendingStudent(ListView):
# Students pending for department approval
context_object_name = 'pending_students'
model = From
template_name = "admin_panel/department/student_detail.html"
def get_queryset(self):
department = self.request.session.get('username')
return From.objects.filter(~Q(d__name==department))
I've used session, to store what type of user is logged in (student/teacher/department).
It seems that you want to return a queryset which excludes certain values. For that I'd use .exclude() instead of filter since it's more explict.
You can check that here
def get_queryset(self):
department = self.request.session.get('username')
queryset = From.objects.exclude(d__name=department)
# In order to print the SQL query you can do this below
# print(queryset.query.__str__())
return queryset
However, if you want to return many students who are not in the From the table you could do something like:
def get_queryset(self):
return Student.objects.filter(from__d__isnull=True)
You can check that here
models.py
class DailyRecordManager(models.Manager):
def get_query_set(self):
qs = super(DailyRecordManager, self).get_query_set().order_by('date_organised')
return qs
class DailyRecord(models.Model):
date_organised = models.DateField('Ogransied Date', help_text=('Enter Date when the program is organised: CCYY-MM-DD'))
program_name = models.TextField('program name',)
venue = models.CharField('venue', max_length = 255, blank=True)
organiser = models.ForeignKey(Organiser, verbose_name = 'Organiser', related_name = 'organisers')
objects = models.Manager()
public = DailyRecordManager()
class Meta:
verbose_name = 'dailyrecord'
verbose_name_plural = 'dailyrecords'
ordering = ['-date_organised']
def __str__(self):
return self.program_name
class Participant(models.Model):
participant = models.CharField(max_length= 50, unique = True)
daily_record = models.ForeignKey(DailyRecord, verbose_name = 'program_name')
class Meta:
verbose_name = 'participant'
verbose_name_plural = 'participants'
def __str__(self):
return self.participant
views.py
class DailyActivityPageView(SingleTableView):
table_class = DailyRecordTable
queryset = DailyRecord.public.all()
# queryset = Participant(DailyRecord.public.all()) is not working
template_name = 'dailyrecord/daily-activity-record.html'
tables.py
class DailyRecordTable(tables.Table):
date_organised = tables.Column('Date')
program_name = tables.Column( 'Program Name')
venue = tables.Column( 'Venue')
organiser = tables.Column( 'Organiser')
participant = tables.Column( 'dailyrecord.participant')
# daily = tables.RelatedLinkColumn()
class Meta:
model = DailyRecord
Now what I need is to display the data from participant table too, corresponding to the daily_record foreign key.
Click this link to view the snapshot. see the last column of the table. I need the data of Participant.partcipant column here
Sorry for poor English.
Thank You
There are two problems here.
First is, that a daily record can have multiple participants. Thus, in order to fill last column you have to aggregate all possible participants into that column (for example as list).
Second is, that you should make Participant backwards related to DailyRecord by adding attribute "related_name" to daily_record in your Participant model, like this:
daily_record = models.ForeignKey(DailyRecord, verbose_name = 'program_name', related_name="participants")
Now, you should simply get participants from daily_record like this:
participants = DailyRecord.public.first().participants.all()
If you had OneToOneField instead of ForeignKey you could add (single) participant to table like this:
participant = tables.Column( "Participant", accessor='participant')
I have the following models in Django:
class campaign(models.Model):
start_date = models.DateField('Start Date')
end_date = models.DateField('End Date')
description = models.CharField(max_length=500)
name = models.CharField(max_length=200)
active_start_time = models.TimeField()
active_end_time = models.TimeField()
last_updated = models.DateTimeField('Date updated',auto_now=True)
active = models.BooleanField(default=True)
client_id = models.ForeignKey('client',on_delete=models.PROTECT)
def __unicode__(self):
return u'%d | %s | %s' % (self.id,self.name, self.description)
class campaign_product(models.Model):
product_id = models.ForeignKey('product',on_delete=models.PROTECT)
last_updated = models.DateTimeField('Date updated',auto_now=True)
campaign_id = models.ForeignKey('campaign',on_delete=models.PROTECT)
class product(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length=500)
sku = models.CharField(max_length=200,blank=True,null=True)
retail_price = models.DecimalField(decimal_places=2,max_digits=11)
discount_price = ((1,'Yes'),(0,'No'))
discounted_price = models.DecimalField(decimal_places=2,max_digits=11,blank=True,null=True)
category_id = models.ForeignKey('category',on_delete=models.PROTECT)
last_updated = models.DateTimeField('Date updated',auto_now=True)
active = models.BooleanField(default=True)
def __unicode__(self):
return u'%d | %s' % (self.id, self.name)
I also have the following serializer:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id')
And the following view set behavior in the urls.py file:
class campaignProductViewSet(viewsets.ModelViewSet):
queryset = campaign_product.objects.filter(campaign_id__start_date__lte=datetime.now(),campaign_id__end_date__gte=datetime.now(),campaign_id__active__exact=True)
serializer_class = campaignProductSerializer
My problem is I need to include the name field from the products model in my query results when for instance a request is made on http://127.0.0.1:8000/campaign_product/1/. Currenly this request returns only the product_id and the campaign_id. I tried making the serializer as follows:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id', 'product.name')
But then the service returns the following error:
Field name `product.name` is not valid for model `campaign_product`.
I event tried using product__name with and without quotes. Without quotes it tells me that there is no such variable, and with quotes it gives the is not valid for model error similar to the above. Heeelp! Getting this extra field is proving to be a pain :-(
What you want will need to look something more like this:
class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
product_name = serializers.CharField(source='product_id.name')
class Meta:
model = campaign_product
fields = ('product_id', 'campaign_id', 'product_name')
P.S. As an unrelated side note, it is generally a convention in Python code to name classes with CamelCase, such as Campaign, CampaignProduct, Product, and CampaignProductSerializer.
Edit: P.P.S. Originally, I had put written the product_name field with source='product.name'. This was actually due to me looking at the code too quickly and making assumptions based on Django conventions. Typically, with a Django ForeignKey, you would name the ForeignKey field after the model you are linking to, rather than explicitly naming it with _id. For example, the CampaignProduct model would typically be written with product = ForeignKey(...) and campaign = ForeignKey(...). In the background, Django will actually use product_id and campaign_id as the database field names. You also have access to those names on your model instances. But the product and campaign variables on your model instances actually return the objects which you are referring to. Hopefully that all makes sense.
I am looking for an elegant and efficient way to pull data out of two tables that have a one-to-one relationship.
Here are my models:
class Contact(models.Model):
name = models.CharField(max_length=100)
country = models.CharField(max_length=100)
status = models.BooleanField()
class ContactDetails(models.Model):
contact_name = models.ForeignKey(Contact)
contact_phone = models.CharField(max_length=100)
contact_fax = models.CharField(max_length=100)
and my view:
def showContact(request):
contacts = ContactDetails.objects.select_related('name').all()
print contacts.values() // debugging in console
return render(request, 'contacts/listContacts.html', { 'contacts': contacts } )
What I try to achieve is a list in my template like:
name, contact_phone, contact_fax, country, status
This again is something that must be so super simple, but I just stuck since a while with this now.
Thanks!
Fields on related models can be accessed via their given relation field.
if somedetails.contact_name.status:
print somedetails.contact_name.country