I have two models Bookings and Presenter, which are setup as a Many to Many Field.
I then have a function called 'export excel' (found on online tutorial) , which exports all of the data from the Booking model to an Excel spreadsheet. Each booking may contain more than one presenter.
Currently the export works but displays a new record for bookings that have more than one presenter assigned. Is it possible to get the presenter name be displayed as a list? rather than duplicating the booking on a new row.
So for example if booking 1 contains two presenters the names will display as ['mark', 'jake']
Queryset used in export excel function
rows= Bookings.objects.all().exclude(status='Cancelled').values_list(
'id', 'program_type', 'delivery_method', 'booking_date', 'booking_time', 'duration', 'school_name', 'year_level', 'street', 'suburb', 'post_code',
'contact_name', 'email', 'phone_number', 'comments', 'students_attending', 'status', 'presenter__name')
Models
class Presenter(models.Model):
id = models.BigAutoField(primary_key=True)
name = models.CharField(max_length=80)
email = models.EmailField()
phone_number = models.CharField(max_length=10)
role = models.CharField(max_length=50)
def __str__(self):
return self.name
class Bookings(models.Model):
statuses = [
('TBC', 'TBC'),
('Confirmed', 'Confirmed'),
('Completed', 'Completed'),
('Cancelled', 'Cancelled'),
]
id = models.BigAutoField(primary_key=True)
program_type = models.CharField(max_length=40)
delivery_method = models.CharField(max_length=40)
booking_date = models.DateField()
booking_time = models.CharField(max_length=10)
duration = models.CharField(max_length=10)
school_name = models.CharField(max_length=120)
year_level = models.CharField(max_length=10)
street = models.CharField(max_length=120)
suburb = models.CharField(max_length=120)
post_code = models.CharField(max_length=10)
contact_name = models.CharField(max_length=80)
email = models.EmailField()
phone_number = models.CharField(max_length=10)
comments = models.TextField(blank=True, null=True)
students_attending = models.CharField(max_length=5)
status = models.CharField(max_length=80, choices=statuses, default='TBC')
presenter = models.ManyToManyField(Presenter)
def __str__(self):
return self.contact_name
Function
def export_excel(request):
# Set the application type
response = HttpResponse(content_type='application/ms-excel')
# Set the file name and extenstion
response['Content-Disposition'] = 'attachment; filename=Advancement Series' +'.xls'
# Create the workbook
wb = xlwt.Workbook(encoding='utf=8')
# Add the worksheets
advancement = wb.add_sheet('Advancement')
# Set the starting row number
advancement_row_num = 0
# Set the font style
font_style = xlwt.XFStyle()
font_style.font.bold = True
font_style.font.name = 'calibri'
# Set the worksheet columns
advancement_columns = ['Booking ID', 'Program Type', 'Delivery Method', 'Booking Date', 'Booking Time', 'Duration', 'School Name', 'Year Level', 'Street', 'Suburb','Post Code', 'Contact Name', 'Email', 'Phone Number', 'Comments', ' Students Attending', 'Status', 'Presenter']
for col_num in range(len(advancement_columns)):
advancement.write(advancement_row_num, col_num, advancement_columns[col_num], font_style)
# Set the font style for non headings
font_style = xlwt.XFStyle()
font_style.font.name = 'calibri'
# Adds the values from the Bookings table
rows= Bookings.objects.all().exclude(status='Cancelled').values_list(
'id', 'program_type', 'delivery_method', 'booking_date', 'booking_time', 'duration', 'school_name', 'year_level', 'street', 'suburb', 'post_code',
'contact_name', 'email', 'phone_number', 'comments', 'students_attending', 'status', 'presenter__name')
for row in rows:
advancement_row_num+=1
for col_num in range(len(row)):
advancement.write(advancement_row_num, col_num, str(row[col_num]), font_style)
wb.save(response)
return response
Managed to resolve this using the Django import-export.
https://django-import-export.readthedocs.io/en/latest/getting_started.html
Related
I have following query that I ran to create a database view inside my SQLite database:
CREATE VIEW customerview AS
SELECT
a.id
, name
, email
, vat
, street
, number
, postal
, city
, country
, geo_lat
, geo_lon
, customer_id
, is_primary
FROM customerbin_address a
, customerbin_customer b
WHERE b.id = a.customer_id
AND a.is_primary = 1
In models.py I added the model:
class Customerview(models.Model):
name = models.CharField(max_length=100, db_column='name')
email = models.EmailField(unique=True, db_column='email')
vat = VATNumberField(countries=['NL', 'BE', 'FR', 'DE', 'UK'], blank=True, null=True, db_column='vat')
street = models.CharField(max_length=100, db_column='street')
number = models.IntegerField(null=True, db_column='number')
postal = models.IntegerField(null=True, db_column='postal')
city = models.CharField(max_length=100, db_column='city')
country = CountryField(db_column='country')
is_primary = models.BooleanField(null=False, db_column='is_primary')
geo_lat = models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True, db_column='geo_lat')
geo_lon = models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True, db_column='geo_lon')
class Meta:
managed = False
db_table = 'customerview'
and in admin.py I altered the list:
#admin.register(models.Customerview)
class CustomerviewAdmin(admin.ModelAdmin):
list_display = ('name', 'email', 'vat', 'street', 'number', 'postal', 'city', 'country', 'is_primary', 'geo_lat', 'geo_lon')
readonly_fields = ('name', 'email', 'vat', 'street', 'number', 'postal', 'city', 'country', 'is_primary', 'geo_lat', 'geo_lon',)
How do I programatically add the database view with the query above in my application?
Django's migrations framework lets you execute raw SQL - https://docs.djangoproject.com/en/3.1/ref/migration-operations/#runsql
So, you could create an empty migration (manage.py makemigrations <appname> --empty) and then edit it to execute your view-creating SQL via a migrations.RunSQL() call.
Maybe you should try this with the get_view_str method https://pypi.org/project/django-database-view/#description
I can't get "list_display" to display field from related table.
models.py
class product(models.Model):
product_id = models.AutoField(primary_key=True)
EAN = models.CharField(unique=True, editable=False, max_length=13)
Product_name = models.CharField(max_length=50)
class price(models.Model):
price_id = models.AutoField(primary_key=True)
EAN = models.ForeignKey(product, to_field="EAN", on_delete=models.CASCADE)
Vendor = models.ForeignKey(vendor, to_field="Vendor_name", on_delete=models.CASCADE)
Qty = models.CharField(max_length=15)
Price = models.DecimalField(max_digits=8, decimal_places=2, null=True)
panels = [
FieldPanel('EAN'),
FieldPanel('Vendor'),
FieldPanel('Qty'),
FieldPanel('Price'),
]
hooks.py
class price_admin(ModelAdmin):
model = pricelist
menu_label = 'price'
menu_icon = 'pilcrow'
menu_order = 300
add_to_settings_menu = False
exclude_from_explorer = False
list_display = ('EAN_id', 'Vendor_id', 'Price') # <-Here I have a problem
list_filter = ('Vendor_id__Name',)
search_fields = ('Vendor_id__Name', 'EAN_id__EAN')
I'm able to get "Vendor_id__Name" to work in "list_filter" and "search_fields", but when I put "Vendor_id__Name" to list_display, I get this error:
AttributeError: Unable to lookup 'EAN_id__Product_name' on price or price_admin
So, what is the right way to display field(Vendor_id__Name in my case) from related table?
Any help would be really appreciated!!
As Ivan Starostin noticed you have a typo in related field name. Other option you can use - a method field or basically - a callable that list display do accept:
class price_admin(ModelAdmin):
...
list_display = ('vendor_name', # other fields)
def vendor_name(self, obj):
return obj.EAN.Product_name
vendor_name.short_description = 'Vendor name'
the problem about 2 things ; First of all in admin panel and webpage foreign keys are shown as object(1) ,Yes I know the solution of this we use str stuff but when I try to compare id of them it takes the value of str function result let me show in code;
Im checking logged in user's connected company id that equals to only students who are connected with same company
model.py - Student
class Student(models.Model):
id = models.AutoField(primary_key=True, verbose_name='StudentID')
parentid = models.ForeignKey(Parent, on_delete=models.CASCADE, verbose_name='ParentID')
companyid = models.ForeignKey(Company, on_delete=models.CASCADE, verbose_name='CompanyID')
classid = models.ForeignKey(Classes, on_delete=models.CASCADE, verbose_name='ClassID')
gender = models.CharField(max_length=1, default='N', verbose_name='Gender')
name = models.CharField(max_length=30, verbose_name='Name')
surname = models.CharField(max_length=30, verbose_name='Surname')
dob = models.DateTimeField(verbose_name='Doğum Yılı')
bloodtype = models.ForeignKey(BloodType, on_delete=models.CASCADE, verbose_name='Blood Type')
status = models.BooleanField(verbose_name='State')
list_display = ('id', 'parentid', 'companyid', 'classid', 'gender', 'name', 'surname', 'dob', 'bloodtype', 'status')
def __str__(self):
return "%s %s - %s" % (self.name, self.surname, self.gender)
model.py - Company
class Company(models.Model):
id = models.AutoField(primary_key=True, verbose_name='CompanyID')
name = models.CharField(
max_length=100, verbose_name='Company Name')
contactname = models.CharField(max_length=30)
contactsurname = models.CharField(
max_length=30)
address = models.CharField(max_length=200)
city = models.CharField(max_length=20)
phone = models.CharField(max_length=12)
weburl = models.URLField(max_length=80)
email = models.CharField(max_length=80)
studentcapacity = models.BigIntegerField(verbose_name='Student Capacity')
classcapacity = models.BigIntegerField(verbose_name='Class Capacity')
notes = models.TextField(max_length=200)
status = models.BooleanField(verbose_name='State')
list_display = ('id', 'name', 'contactname', 'contactsurname', 'address', 'city', 'phone',
'weburl', 'email', 'studentcapacity', 'classcapacity', 'notes', 'status')
def __str__(self):
return "%s - %s" % (self.id, self.name)
views.py
#login_required()
def student_update(request, pk):
student = get_object_or_404(Student, pk=pk)
usercompanyid = UserProfile.objects.filter(userid=request.user.id).only('companyid')
print('before control')
a = usercompanyid.values_list('companyid', flat=True)[0]
print(a)
print(student.companyid)
if student.companyid == a:
print('passed if')
if request.method == 'POST':
form = StudentForm(request.POST, instance=student)
else:
form = StudentForm(instance=student)
return save_student_form(request, form, 'student_update_partial.html')
else:
return view_404(request)
at if state " student.companyid == a: " = Company ID - Company Name , output: 1 -Test CompanyName = 1 , I need it to return only field I call which is companyid, I know it is allias to "companyID - companyName". Is it possible to fix this with another way , I'm not pro of django python , just trying to do some project for learning if it's a dump question sorry for all :)
When you do this:
companyid = models.ForeignKey(...)
The database schema would actually have a field name of companyid_id.
So in your case, if you want to compare object IDs then you actually need to do this:
if student.companyid_id == a:
To avoid confusion, I would advise you not to append the 'id' part to your Django model field names.
There's a lot of unnecessary messing around with only and values here. No need for any of that. Just compare the objects directly:
def student_update(request, pk):
student = get_object_or_404(Student, pk=pk)
if student.companyid == request.userprofile.companyid:
...
As an aside, you shouldn't call your foreign keys "companyid", "parentid" etc; they're not IDs, they're objects. Call them "company", "parent" etc.
I am relatively new to django and have a problem regarding passing some information from one model to another. Its not quite inheritance but rather ensuring that a parent model passes certain information upon creating a child model. So I have two models, one for Events and another for Occurrences. The Events is run via admin and when you create an event it also creates occurrences for that event. My problem is that each event is in a specific city and I would like it to pass the city value to the occurrences it creates so that I can use that city value in a filter. It should be noted, an occurrence is not an Event so this is not simply just multi-table inheritance. How do I pass on this value?
Models.py
# The events are models that contain the what and where.
class Event(models.Model):
class Meta:
verbose_name_plural = 'Events'
verbose_name = 'Event'
created = models.DateTimeField(auto_now=False, auto_now_add=True, blank = False, null = False, verbose_name = 'Creation Date')
#Date Event was edited for the last time
updated = models.DateTimeField(auto_now=True, auto_now_add=False, blank = False, null = False, verbose_name = 'Updated')
#Name of the event
name = models.CharField(max_length = 400, null=True, blank = False, verbose_name = 'Name')
#Event Description
description = models.TextField(max_length = 10000, null=True, blank = True, verbose_name = 'Description')
#Event City
city = models.ForeignKey(City, null=True, blank = False, verbose_name = 'City')
#Event Location
location = ChainedForeignKey(
ProfileVenue,
chained_field="city",
chained_model_field="city",
show_all=False,
auto_choose=True,
sort=True,
default=1,)
#Price Entity
price = models.ForeignKey(Price, null=True, blank = True,)
#Max Number of participants
max_participants = models.IntegerField(null=True, blank = False, verbose_name = 'Nr. Participants')
#Event Language
language = models.ForeignKey(Language, null = True, blank = False)
#Event Type
event_type = models.ForeignKey(EventType, null = True, blank =False, verbose_name='Event Type')
#---------------------------------------------------------------------------
def __unicode__(self):
return "%s:%s" % (self.name, self.location.name)
class Occurrence(models.Model):
class Meta:
verbose_name_plural = 'Sessions'
verbose_name = 'Session'
created = models.DateTimeField(auto_now=False,
auto_now_add=True, blank = False, null = False, verbose_name = 'Creation Date')
updated = models.DateTimeField(auto_now=True,
auto_now_add=False, blank = False, null = False, verbose_name = 'Updated')
event = models.ForeignKey(Event,
on_delete=models.CASCADE)
'''
city = ChainedForeignKey(
Event,
chained_field="city",
chained_model_field="city",
show_all=False,
auto_choose=True,
sort=True)
'''
teacher = models.ForeignKey(ProfileTeacher,
null=True, blank = True, verbose_name = 'Teacher')
students = models.ManyToManyField(ProfileStudent,
verbose_name = 'Students', blank=True)
# Max number of students for this group
max_participants = models.IntegerField(null=False,
blank=False, default=5, verbose_name='Max Nr Participants')
# Date and Time for this session
date = models.DateTimeField(auto_now=False,
auto_now_add=False, null=True, blank=True, verbose_name='Date')
# Duration of the class
duration = models.DurationField(default=timedelta(), verbose_name='Duration')
# Language Levels
language_level = models.ForeignKey(LanguageLevel,
null=True, blank=True, verbose_name='Language Level')
# True of teacher was assigned to class
teacher_assigned = models.BooleanField(
default=False, blank=True)
# Status of the Occurrence
# Active --> Class has been created
# Canceled --> Canceled by human admin
# Auto Canceled --> Canceled by the Automation System
# Due --> Class finished. Student Evaluated. Teacher Can get Extraction.
STATUS = (
(1, ('ACTIVE')),
(2, ('CANCELED')),
(3, ('DUE')),
(4, ('AUTO CANCELED')),
)
status = models.IntegerField(choices=STATUS, default=1)
# Evaluated by teacher: True if a teacher evaluated all students
students_ev_by_teacher = models.BooleanField(default=False, verbose_name='Alumnos evaluados')
# If true Send Mails when occurrence canceled to all teachers that are not assigned and students
send_cancel_mail = models.BooleanField(default=True, verbose_name='Enviar Email Cancelar')
# friendlly url
slug = models.SlugField(max_length=300, verbose_name='Occurrence Url', blank=True, null=True)
Event Admin Form that creates Occurences when Events are also created
class EventForm(forms.ModelForm):
list_filter = ['city']
#Frequecy type for periodical events
FREQUENCY = (
('NEVER', ('Nunca')),
# ('DAILY', _('Every Day')),
('WEEKDAY', ('Cada Semana')),
# ('WEEKLY', _('Every Week')),
# ('BIWEEKLY', _('Every 2 Weeks')),
# ('MONTHLY', _('Every Month')),
)
# Weekday choices
WEEKDAYS = (
( 0, ('Lunes')),
( 1, ('Martes')),
( 2, ('Miercoles')),
( 3, ('Jueves')),
( 4, ('Viernes')),
( 5, ('Sabado')),
( 6, ('Domingo')),
)
#Date of the first Occurrence
start_date = forms.SplitDateTimeField(
widget = widgets.AdminSplitDateTime(),
help_text='Date and hour of the Event.',
required= True,
)
#Limit Date for last Occurrence: no hour needed
end_date = forms.SplitDateTimeField(
widget = widgets.AdminSplitDateTime(),
required = False,
help_text='Date and hour of the Event.',
)
#Event frequency tipe: weekly and never supported only
freq = forms.ChoiceField(
choices=FREQUENCY,
initial='WEEKDAY',
label = 'Tipo Periodicidad'
)
#The event wwill occure on this weekday once a week until the end date
weekday = forms.ChoiceField(
choices=WEEKDAYS,
widget=forms.RadioSelect(),
initial=1
)
#Event Duration in hours: stored as timedelta in database
duration = forms.DurationField(
initial='01:00:00',
)
#Class Meta
class Meta:
model = Event
fields = ('name',
'event_type',
'description',
'city',
'location',
'language',
'price',
'max_participants',
'start_date',
'end_date',
'freq',
'weekday',
'duration',
)
#End Date Validation:
def clean_end_date(self):
if self.cleaned_data['end_date'] > self.cleaned_data['start_date']:
return self.cleaned_data['end_date']
else:
raise ValidationError('End-Date should be higher than Start-Date!', code='invalid')
#End Date Validation: Occurences shall not be created when an event is updated
#This will create too many objects and confusion.
#Save the Validated Form
def save(self, commit=True):
#Getting the cleaned data
freq = self.cleaned_data.get('freq', None)
start_date = self.cleaned_data.get('start_date', None)
end_date = self.cleaned_data.get('end_date', None)
weekday = int(self.cleaned_data.get('weekday', None))
duration = self.cleaned_data.get('duration', None)
#Saving the Event
self.instance.save()
#Loading Language Levels
levels = LanguageLevel.objects.all()
#Calculate Max Participants for Occurrences
#This shall be a function of the type of the event
max_participants = 5;
#Create Occurrences from dates(see dateutil.rrule doc's for details):
if freq == 'NEVER':
for level in levels:
#Check for Future Occurrences:
oc = Occurrence(
date=start_date,
event=self.instance,
duration=duration,
max_participants=max_participants,
language_level=level,
)
oc.save()
#One per week until End_Date
elif freq == 'WEEKDAY':
oc_dates = rrule(WEEKLY, dtstart = start_date, byweekday = weekday, until=end_date)
for oc_date in oc_dates:
for level in levels:
oc = Occurrence(
date=oc_date,
event=self.instance,
duration=duration,
max_participants=max_participants,
language_level=level,
)
oc.save()
#Saving the Event
return super(EventForm, self).save(commit=commit)
You have a foreign key to an Event, with which you can access the city, for example with a property:
class Occurrence(models.Model):
[...]
#property
def city(self):
return self.event.city
No need to duplicate data in your database.
Thanks to #DanielRoseman who provided this answer. My issue here was that I was not using the double-underscore syntax which would enable me to access my "event" attributes. i.e .filter(event__city=cityId). Its fully document here
I'm able to access the correct fields ('author.username') when I execute the query.
But if I run that same query through the serializer, it doesn't print out the select_related model fields.
Should I be specifying all fields, plus the additional fields of the foreignkey model??
views.py
query = Chat.objects.select_related('author').filter(id=chat.id)
print(query) # [<Chat: 108>]
print(query[0]) # 108
print(query[0].author.username) # superman
context = serializers.serialize("json", Chat.objects.select_related('author').filter(id=chat.id))
print("---------")
print(context) # [{"model": "chats.chat", "pk": 108, "fields": {"author": 29, "text": "this is a message", "chatroom": 11, "written_at": "2016-01-07T23:03:28.968Z"}}]
--- Updated ---
views.py
context = ChatSerializer(chat)
# output
{u'text': u'come on', u'chatroom': OrderedDict([(u'id', 11), ('created_at', u'2016-01-07T00:27:28.391467Z'), ('creator', 29), ('participant', 1)]), u'written_at': u'2016-01-08T01:12:20.310776Z', u'author': OrderedDict([(u'id', 29), ('password', u'pbkdf2_sha256$24000$h0whlzx0BleT$4cUWdRkUsPYB7Ia6F+pYxX+31BMhJJfpWiLHfoL9NOY='), ('last_login', u'2016-01-07T00:26:37.907507Z'), ('email', u'superman#gmail.com'), ('username', u'superman'), ('first_name', u'clark'), ('last_name', u'kent'), ('is_active', True), ('is_admin', False), ('joined_on', u'2016-01-06T23:57:43.191484Z'), ('is_online', False), ('is_contractor', False), ('profile_pic', '/media/bicycle_z3NDBPI.jpeg'), ('braintree_id', u'20401140'), ('braintree_client_token', u'eyJ2ZXJzaW9uIjoyLCJhdXRob3JpemF0aW9uRmluZ2VycHJpbnQiOiI1MjIxM2UwZDQ4OGM0MmFkNTYzY2IzMDJlMDBkMmIyMWIwZWEzYzBiNWEzZTg2ZmNhMmJlNWM3MTI5YjNmNGJifGNyZWF0ZWRfYXQ9MjAxNi0wMS0wNlQyMzo1Nzo0NC42MTgzNzQ2NTgrMDAwMFx1MDAyNmN1c3RvbWVyX2lkPTIwNDAxMTQwXHUwMDI2bWVyY2hhbnRfaWQ9ZGZ6amRrdHM1ZnNxeXF0alx1MDAyNnB1YmxpY19rZXk9ZGtta245cDNjNTQzZGhudyIsImNvbmZpZ1VybCI6Imh0dHBzOi8vYXBpLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb206NDQzL21lcmNoYW50cy9kZnpqZGt0czVmc3F5cXRqL2NsaWVudF9hcGkvdjEvY29uZmlndXJhdGlvbiIsImNoYWxsZW5nZXMiOltdLCJlbnZpcm9ubWVudCI6InNhbmRib3giLCJjbGllbnRBcGlVcmwiOiJodHRwczovL2FwaS5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tOjQ0My9tZXJjaGFudHMvZGZ6amRrdHM1ZnNxeXF0ai9jbGllbnRfYXBpIiwiYXNzZXRzVXJsIjoiaHR0cHM6Ly9hc3NldHMuYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJhdXRoVXJsIjoiaHR0cHM6Ly9hdXRoLnZlbm1vLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJhbmFseXRpY3MiOnsidXJsIjoiaHR0cHM6Ly9jbGllbnQtYW5hbHl0aWNzLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb20ifSwidGhyZWVEU2VjdXJlRW5hYmxlZCI6ZmFsc2UsInBheXBhbEVuYWJsZWQiOnRydWUsInBheXBhbCI6eyJkaXNwbGF5TmFtZSI6ImthbGxhcm9vIiwiY2xpZW50SWQiOm51bGwsInByaXZhY3lVcmwiOiJodHRwOi8vZXhhbXBsZS5jb20vcHAiLCJ1c2VyQWdyZWVtZW50VXJsIjoiaHR0cDovL2V4YW1wbGUuY29tL3RvcyIsImJhc2VVcmwiOiJodHRwczovL2Fzc2V0cy5icmFpbnRyZWVnYXRld2F5LmNvbSIsImFzc2V0c1VybCI6Imh0dHBzOi8vY2hlY2tvdXQucGF5cGFsLmNvbSIsImRpcmVjdEJhc2VVcmwiOm51bGwsImFsbG93SHR0cCI6dHJ1ZSwiZW52aXJvbm1lbnROb05ldHdvcmsiOnRydWUsImVudmlyb25tZW50Ijoib2ZmbGluZSIsInVudmV0dGVkTWVyY2hhbnQiOmZhbHNlLCJicmFpbnRyZWVDbGllbnRJZCI6Im1hc3RlcmNsaWVudDMiLCJiaWxsaW5nQWdyZWVtZW50c0VuYWJsZWQiOnRydWUsIm1lcmNoYW50QWNjb3VudElkIjoia2FsbGFyb28iLCJjdXJyZW5jeUlzb0NvZGUiOiJVU0QifSwiY29pbmJhc2VFbmFibGVkIjpmYWxzZSwibWVyY2hhbnRJZCI6ImRmempka3RzNWZzcXlxdGoiLCJ2ZW5tbyI6Im9mZiJ9'), ('payment_method_nonce', u'dbd01080-35e2-4a3b-a695-560491a14567'), ('payment_method_token', u'cfty3w')])}
console.log() output
ChatSerializer(<Chat: 118>):
author = NestedSerializer(read_only=True):
id = IntegerField(label='ID', read_only=True)
password = CharField(max_length=128)
last_login = DateTimeField(allow_null=True, required=False)
email = EmailField(max_length=255, validators=[<UniqueValidator(queryset=User.objects.all())>])
username = CharField(max_length=80)
first_name = CharField(max_length=45)
last_name = CharField(max_length=45)
is_active = BooleanField(required=False)
is_admin = BooleanField(required=False)
joined_on = DateTimeField(read_only=True)
is_online = BooleanField(required=False)
is_contractor = BooleanField(required=False)
profile_pic = ImageField(allow_null=True, required=False)
braintree_id = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
braintree_client_token = CharField(allow_blank=True, allow_null=True, max_length=2000, required=False)
payment_method_nonce = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
payment_method_token = CharField(allow_blank=True, allow_null=True, max_length=255, required=False)
text = CharField(max_length=255)
chatroom = NestedSerializer(read_only=True):
id = IntegerField(label='ID', read_only=True)
created_at = DateTimeField(read_only=True)
creator = PrimaryKeyRelatedField(queryset=User.objects.all())
participant = PrimaryKeyRelatedField(queryset=Contractor.objects.all())
written_at = DateTimeField(read_only=True)
The Django's serializer doesn't support it: ticket. I suggest you using the Django Rest Framework.
Joining the Tables using the Foreign Key is what you are searching for I guess
READ IT CAREFULLY IT'S LONG BUT WORTH READING
Just assume that you have 2 models:- Employee and Organization
Organization(models.Model):
organization_name = models.CharField()
Employee(models.Model):
employee_name = models.CharField()
employee_organization= models.ForeignKey(Organzation,on_delete=models.CASCADE)
And you have to access Employee Model in the frontend but the data you receive is:
data : {
employee_name:"some_employee_name",
employee_organization:"some_org_id" #Here you are getting org_id but
#that's not what you want I assume
}
But what you really want to get in the frontend is:-
data : {
employee_name:"some_employee_name",
employee_organization: {
organization_name:"some_organization_name"
}
}
So that you can access the "Organization Name" instead of "Organization ID". This is called Joining the table using the Foreign Key.
For that you have to create the Serializers for the models like this:-
OrganizationSerializer(serializer.ModelSerializer):
model = models.Organization
field = "__all__"
EmployeeSerializer(models.Model):
employee_organization = OrganizationSerializer() # This does the trick
model = models.Employee
fields = "__all__"
You should return the data to the frontend using the EmployeeSerializer normally in your View like this:-
class EmployeeView(APIView):
def get(self, request, format=None):
queryset= models.Employee.objects
.select_related("employee_organization")
.get(id="some_employee_id")
serializer = serializers.EmployeeSerializer(queryset)
return Response(serializer.data)
Now you will get the required data as:-
data : {
employee_name:"some_employee_name",
employee_organization: {
organization_name:"some_organization_name"
}
}
Now you can extract the "organization_name" however you want.