I have created a model named Appointment which stores appointment details of a patient whose details i am storing in the res.users table. I have used Many2One multiplicity between the Appointment and the patient using the userId.
Appointment model contains the following:
appointment_details = fields.Text(string='Appointment details', required=True)
appointment_date = fields.Date(string='Appointment date', required=True)
patient_user_id = fields.Many2one('res.users', string='Patient id', default=lambda self: self.env.uid, required = True)
I added the following fields in the res.users model:
phone_number = fields.Integer(string='Phone number', required=True)
address = fields.Text(string='Address', required=True)
When displaying the Appointment details in the form view, the patient's name appears. But, i want to display his phone and address as well.
Add following fields in your 'appointment' class.
Note : keep the datatype same of res.users fields and appointment calss fields
phone_number = fields.Integer(string='Phone number',related='patient_user_id.phone_number')
address = fields.Text(string='Address',related='patient_user_id.address')
Related
In my Django Rest Framework project, I have a ForeignKey relationship between two models:
class Book(models.Model):
...
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True, null=True)
...
class Category(models.Model):
name = models.CharField(max_length=100, blank=False)
As you can see, a Book can belong to a Category but it does not have to. That means the 'category' field could be null.
So, in my views.py, any Book instance can be updated/patched if the user wants to assign a certain Book to a particular Category. That views.py update method looks like this:
class UpdateBooksCategory(generics.GenericAPIView):
'''
Class-based view to update the 'category' field of a Book instance.
'''
serializer_class = BookSerializer
permission_classes = [IsAuthenticated]
def patch(self, request,*args, **kwargs):
# get the Book instance first
book = Book.objects.get(pk=request.data.get('bookId'))
# if it is not assigned to a Category, then assign it
if book and not book.category:
book.category = Category.objects.get(name=request.data.get('categoryName'))
book.save()
serializer = self.get_serializer(book, context={"request": request})
return Response(serializer.data)
# otherwise, return a generic response
return Response({'response': "You have already put the selected Book in a Category."})
If you can see, first I get the Book instance that the user wants to update by using the Book's ID. If its Category field is not already filled, I get a Category instance using the given category name and assign it.
For the sake of completeness, here are my serializer classes:
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id', 'name']
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ['id', /*some other fields*/,..., 'category']
So, finally my question: I wanted to know if this is the preferred way of updating a ForeingKey field like this? I mean looking at the UpdateBooksCategory class-based view, is this the right way of doing it? The code works ( I tested it with PostMan) but since I am new to DRF I wanted to know if such an updating process is correct.
You can change your BookSerializer:
class BookSerializer(serializers.ModelSerializer):
category_id = serializers.IntegerField(write_only=True)
category = CategorySerializer(read_only=True)
class Meta:
model = Book
fields = [
'id',
# some other fields,
'category',
'category_id',
]
category will be a nested data that is read only, then setting the category will be by including the category_id in your requests.
My data consists of some products, which are defined in FdProduct model:
# models.py:
class FdProduct(models.Model):
product_id = models.CharField(max_length=10, primary_key=True)
name = models.CharField(max_length=40)
active = models.BooleanField(default=True)
def __str__(self):
return self.product_id
# serializers.py:
class FdProductSerializer(serializers.ModelSerializer):
product_id = serializers.RegexField(regex='^\d{3}\.\d{6}$', max_length=10, min_length=10, allow_blank=False)
name = serializers.CharField(min_length=6, max_length=50, allow_blank=False)
class Meta:
model = FdProduct
fields = '__all__'
For each existing product I can prepare a configuration and save it using a model called SavedConfiguration:
# models:
class SavedConfiguration(models.Model):
saved_conf_id = models.CharField(max_length=13, primary_key=True)
saved_config = models.TextField()
product = models.ForeignKey(FdProduct, on_delete=models.CASCADE, default=0)
session_id = models.CharField(max_length=40, default=0)
creation_date = models.DateTimeField(auto_now=False, auto_now_add=True)
def __str__(self):
return str(self.saved_conf_id)
# serializers.py:
class SavedConfigurationSerializer(serializers.ModelSerializer):
saved_conf_id = serializers.RegexField(regex='^sc\d{2}', allow_blank=False)
saved_config = serializers.CharField(min_length=6)
session_id = serializers.RegexField(regex='^se\d{2}', allow_blank=False)
class Meta:
model = SavedConfiguration
fields = '__all__'
By connecting the SavedConfiguration with FdProduct model with use of ForeignKey I ensure that a product exists in the database when I configure it and want to save the configuration.
I'd like to introduce two things more: the first one would be a model for storing just a product_id and an array containing all saved_conf_ids for that product:
# models.py:
class ConfigOptions(models.Model):
product_id = ...
saved_conf_id = [...]
For example, if I configured a couple of times two products, Product One and Product Three, I may have data like this:
- Product One:
- C_ID_0023
- C_ID_0025
- C_ID_0032
- Product Three:
- C_ID_0149
- C_ID_0273
My question now is, how to construct such model and serializer for which records are created (copied) into ConfigOptions model table each time SavedConfiguration is saved?
Second question: I'm thinking about creating another model, say ConfigPresenceCheck, which would receive POST requests and based on that would check if saved product configurations exist (so, fetching them from ConfigOptions or returning 404), and if they exist, would return them together with all parameters from SavedConfiguration (e.g. saved_config, session_id, etc.).
Please give me directions how to build such models. I'd also appreciate some good tutorials related to
constructing Django models.
I think you should use many to many fields instead of foreign key, from my understanding many products can have many saved configurations and vice versa, at database level many to many fields are stored by creating a table any way.
I have to build a queryset in which we can select all the objects from a field in a model and compare to the field in another model...
For Eg:- i have to select all the objects in docid field with corresponding amount from profitandloss model and compare to docid with corresponding amount from balancesheet model
Model -1
Class Profitandloss(models.Model):
docid = models.charfield(max_length=15)
amount = models.integerfield(default=0)
class balancesheet(models.Model):
docid = models.charfield(max_length=15)
amount = models.integerfield(default=0)
Your model design needs changing. you should have document as another model and link document model to your profileandloss and balancesheet model as foriegnkey This will allow ORM search effectively
class Company(models.Model):
_name="account.company.name"
name=fields.Char(string="Company Name")
address=fields.Text(string="Address")
mobile_no=fields.Char(string="Mobile Number", size=10)
and another model :
class New(models.Model):
_inherit ='sale.order'
company = fields.Many2one("account.company.name")
How to extract all fields like name, address, mobile_no in class New
If you select a company for a record in your New class the other fields should be populated with the related fields from the selected company.
class New(models.Model):
_inherit ='sale.order'
company = fields.Many2one("account.company.name")
name=fields.Char(related='company.name',string="Company Name")
address=fields.Text(related='company.address',string="Address")
mobile_no=fields.Char(related='company.mobile_no',string="Mobile Number", size=10)
(untested)
class NewModel(models.Model):
_name="account.company.name"
name=fields.Char()
class InheritedModel(models.Model):
_inherit="sale.order"
company_id=fields.Many2one('account.company.name")
company_id_name=fields.Char(related='company_id.name',string="Company Name")
company_id_name2=fields.Char(related=['company_id','name'],string="Company Name")
class PortalContent(models.Model):
movies = models.ForeignKey(Movie, db_column="movies_id")
portalID = models.IntegerField()
projectID = models.IntegerField(default=0)
contentType = models.CharField(max_length=100)
licenseTerms = models.TextField()
createDate = models.DateTimeField(auto_now=True)
I have the above model .This model has a field which is related to Movie Model via foreign key.
Now when I view the list /portalContent/1/
the data takes more than 2 seconds to load . The movie table only has 20K records .
Not sure why this is taking so much time . I used the debug_toolbar and its showing one query i.e select * from movies as taking 1.6s . Both the tables have index defined .
Can anyone guide me
Thanks #Demux
We need to remove browsable API renderer from your list of supported renderers for the view.
You can do this globally like so:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
)
}
Or on a per-view basis like so:
class MyView(...):
renderer_classes = [renderers.JSONRenderer]