How can I see the Subject name in the django-rest-framework dropdown? Now it just says Subject object.
Here are my models:
class Subject(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
owner = models.ForeignKey('auth.User', related_name='subjects')
code = models.CharField(max_length=50)
name = models.CharField(max_length=50)
description = models.CharField(max_length=50)
class Meta:
ordering = ('created',)
def __unicode__(self):
return '%s' % (self.name)
class Grade(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
owner = models.ForeignKey('auth.User', related_name='grades')
code = models.CharField(max_length=3)
requirements = models.CharField(max_length=200)
ranking = models.IntegerField()
subject = models.ForeignKey(Subject, related_name='grades', on_delete=models.CASCADE)
class Meta:
unique_together = ('subject', 'ranking')
ordering = ('ranking',)
def __unicode__(self):
return '%d: %s' % (self.ranking, self.code)
I see you have defined __unicode__ for your model. But perhaps you are using Python 3, in which case for Django models you need to define __str__ not __unicode__
class Subject(models.Model):
...
def __str__(self): # Use this in Python 3
return '%s' % (self.name)
Unrelated, but this is a more succinct return:
def __str__(self):
return self.name
Related
Is there a way to give the relations their name instead of calling them "object-n" like shown below?
Here is the code for the two models in question:
class jobTag(models.Model):
Tag = models.CharField(max_length=15)
def __str__(self):
return self.Tag
class job(models.Model):
Company_name = models.CharField(max_length=200, null=True, blank= True)
Position = models.CharField(max_length=200, null=False, blank=False)
Type = models.ForeignKey(jobType, default=" ",verbose_name="Type", on_delete=models.SET_DEFAULT)
Industry = models.ForeignKey(jobIndustry, default=" ", verbose_name="Industry", on_delete=models.SET_DEFAULT)
Location = models.ForeignKey(jobLocation, default=" ", verbose_name="Location", on_delete=models.SET_DEFAULT)
Role_description = tinymce_models.HTMLField(default="")
Role_requirements = tinymce_models.HTMLField(default="")
Role_duties = tinymce_models.HTMLField(default="")
Special_benefits = tinymce_models.HTMLField(default="")
Date_posted = models.DateTimeField(auto_now_add=True)
tags = models.ManyToManyField('jobTag', related_name="job-tags+", blank=True)
def time_posted(self):
return humanize.naturaltime(self.Date_posted)
def __str__(self):
return self.Position
class Meta:
verbose_name_plural = "Jobs"
UPDATE:
I tried adding a proxy through-table in models.py but it still doesn't solve the problem. Here:
class jobjobTagProxy(job.tags.through):
class Meta:
proxy = True
def __str__(self):
return self.job.Position + ' // ' + self.tags.Tag
What am I doing wrong?
My models:
class Ingredient(models.Model):
BASE_UNIT_CHOICES = [("g", "Grams"), ("ml", "Mililiters")]
CURRENCY_CHOICES = [("USD", "US Dollars"), ("EUR", "Euro")]
ingredient_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
base_unit = models.CharField(max_length=2, choices=BASE_UNIT_CHOICES)
cost_per_base_unit = models.FloatField()
currency = models.CharField(
max_length=3, choices=CURRENCY_CHOICES, default="EUR")
def __str__(self):
return self.name
class RecipeIngredient(models.Model):
quantity = models.FloatField()
ingredient_id = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
def __str__(self):
return f"{self.quantity} / {self.ingredient_id}"
class Recipe(models.Model):
recipe_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
ingredients = models.ManyToManyField(RecipeIngredient)
date_created = models.DateTimeField('Date Created')
def __str__(self):
return f"{self.name}, {self.ingredients}"
When I use the admin page, it has this + button that allows me to create new ingredient/quantity combinations
like this
But when I try to use it from a form in my code it looks like
this
Here is my form code:
class AddRecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ['name', 'ingredients', 'date_created']
You should write the 'widgets' for each field in you Form that need configuration.
Check the documentation 'Widgets in forms', or even, you can define your own Widgets.
Helo everyone. I have a little problem. I've create a models:
class Cudzoziemiec(models.Model):
imie = models.CharField(max_length=80, verbose_name="Imię", unique=False)
nazwisko = models.CharField(max_length=150, verbose_name="Nazwisko", unique=False)
class Meta:
verbose_name = 'Cudzoziemca'
verbose_name_plural = 'Cudzoziemcy'
def __str__(self):
return self.nazwisko
class Umowa(models.Model):
RODZAJ_UMOWY = (
('UP', 'Umowa o pracę'),
('UZ', 'Umowa zlecenie'),
('UD', 'Umowa o dzieło'),
)
osoba = models.ForeignKey(Cudzoziemiec, on_delete=models.CASCADE, verbose_name="Wybierz cudzoziemca")
umowa_rodzaj = models.CharField(max_length=250,choices=RODZAJ_UMOWY, verbose_name="Rodzaj umowy")
nr_umowy = models.PositiveIntegerField()
umowa_od = models.DateField(auto_now=False, auto_now_add=False, verbose_name="Data rozpoczęcia pracy")
umowa_do = models.DateField(auto_now=False, auto_now_add=False, verbose_name="Data zakończenia pracy")
class Meta:
verbose_name = 'Umowę'
verbose_name_plural = 'Umowy'
def __str__(self):
return self.nr_umowy
In panel admin everything works ok. But how to display "imie"+"nazwisko" in panel admin in case when I want to create a new record in Umowy. Now I have only "nazwisko" if I want to add new record via Umowa class, selected a "osoba" in that class.
EDIT:
When I want to add new record the django return me a error:
__str__ returned non-string (type int)
Not sure if that's what you want, but usually the string representation used in the select input generated by Django forms use the __str__ method:
class Cudzoziemiec(models.Model):
imie = models.CharField(max_length=80, verbose_name="Imię", unique=False)
nazwisko = models.CharField(max_length=150, verbose_name="Nazwisko", unique=False)
class Meta:
verbose_name = 'Cudzoziemca'
verbose_name_plural = 'Cudzoziemcy'
def __str__(self):
return '{} {}'.format(self.imie , self.nazwisko)
Or equivalent result:
def __str__(self):
return '%s %s' % (self.imie , self.nazwisko)
Or if you are using Python 3.6+
def __str__(self):
return f'{self.imie} {self.nazwisko}'
About the "non-string" error, it's because __str__ should return a string object. In your second case, you are returning a self.nr_umowy, which is a PositiveIntegerField.
You have to cast it:
def __str__(self):
return str(self.nr_umowy)
I would like to request some assistance regarding this matter,
I am fairly new to django and I like it so far.
I have the following model:
class Courses_list(models.Model):
Abbreviation = models.CharField(max_length=100, unique=True)
Course = models.CharField(max_length=100, unique=True)
def save(self, force_insert=False, force_update=False):
self.Abbreviation = self.Abbreviation.upper()
super(Courses_list, self).save(force_insert, force_update)
def __unicode__(self):
return self.Abbreviation
class Job_Posting(models.Model):
Job_Position = models.CharField(max_length=30, null=True, unique=True)
def __unicode__(self):
return self.Job_Position
class Educational_Requirement(models.Model):
fkey = models.ForeignKey('Job_Posting')
Course = models.ForeignKey('Courses_list')
And form:
class CustomField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.Course
class SampleForm(ModelForm):
COURSE = CourseField(queryset=Educational_Requirement.objects.all())
I am saving at:
class MyModel(ModelForm):
course = models.CharField(max_length=50, null = True, blank = True)
In the frontend of my test app SampleForm shows the Course as choices but how do I get the actual value of Course and save it? Because when I view my saved COURSE in the admin it displays Educational_Requirement Object instead of the value I have seen on the dropdown. I can't use __unicode__ at Educational_Requirement as it would raise an error.
I have updated my answer based on your updated question.
Why not use a ManyToManyField and let Django's ORM handle the educational_requirement relationship for you? This way you can use Django's reverse lookup to handle the ForeignKey's name.
class Courses_list(models.Model):
Abbreviation = models.CharField(max_length=100, unique=True)
Course = models.CharField(max_length=100, unique=True)
def save(self, force_insert=False, force_update=False):
self.Abbreviation = self.Abbreviation.upper()
super(Courses_list, self).save(force_insert, force_update)
def __unicode__(self):
return self.Abbreviation
class Meta:
verbose_name = 'Course'
verbose_name_plural = 'Courses'
class Job_Posting(models.Model):
Job_Position = models.CharField(max_length=30, null=True, unique=True)
educational_requirement = models.ManyToManyField(Courses_list)
def __unicode__(self):
return self.Job_Position
class Meta:
verbose_name = 'Job Position'
verbose_name_plural = 'Job Positions'
I have a card model with some workouts models, each workouts has exactly the same data: exercise name, repetitions..etc The workouts are 7, one for each day of the week. So I wrote 7 models with exactly the same data, in this way in the admin model I have 7 workouts and for each I can add "+" how many exercises I want (using inlines)
Is there a way to write the workout model only once and then have the possibility to add it many times in the admin interface? (each time I add a workout, I would like to be able to add exercise name, repetitions etc.. in the same admin view)
class Card(models.Model):
number = models.IntegerField()
name = models.CharField(max_length=50)
surname = models.CharField(max_length=50)
trainer = models.CharField(max_length=50, blank=True, null=True)
#Card status
creation = models.DateField(auto_now_add=True)
expiration = models.DateField(blank=True, null=True)
#Member status
subscription = models.DateField(blank=True, null=True)
def __str__(self):
return u'%s %s' % (self.surname, self.name)
class Meta:
unique_together = (("number"),)
class Exercise(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return u'%s' % (self.name)
class Series(models.Model):
number = models.IntegerField()
def __str__(self):
return u'%s' % (self.number)
class Meta:
verbose_name = 'Series'
verbose_name_plural = 'Series'
class Repetitions(models.Model):
number = models.IntegerField()
def __str__(self):
return u'%s' % (self.number)
class Meta:
verbose_name = 'Repetition'
verbose_name_plural = 'Repetitions'
class Executions(models.Model):
mode = models.CharField(max_length=50)
def __str__(self):
return u'%s' % (self.mode)
class Meta:
verbose_name = 'Execution'
verbose_name_plural = 'Executions'
class Rest(models.Model):
time = models.IntegerField()
def __str__(self):
return u'%s' % (self.time)
class Meta:
verbose_name = 'Rest'
verbose_name_plural = 'Rest'
class Exercise1(models.Model):
card = models.ForeignKey(Card)
exercise = models.ForeignKey(Exercise)
series = models.ForeignKey(Series)
repetitions = models.ForeignKey(Repetitions)
executions = models.ForeignKey(Executions)
rest = models.ForeignKey(Rest)
class Meta:
verbose_name = 'Exercise'
verbose_name_plural = 'Workout 1'
def __str__(self):
return u'%s' % (self.exercise)
class Exercise2(models.Model):
card = models.ForeignKey(Card)
exercise = models.ForeignKey(Exercise)
series = models.ForeignKey(Series)
repetitions = models.ForeignKey(Repetitions)
executions = models.ForeignKey(Executions)
rest = models.ForeignKey(Rest)
class Meta:
verbose_name = 'Exercise'
verbose_name_plural = 'Workout 2'
def __str__(self):
return u'%s' % (self.exercise)
class Exercise3(models.Model):
card = models.ForeignKey(Card)
exercise = models.ForeignKey(Exercise)
series = models.ForeignKey(Series)
repetitions = models.ForeignKey(Repetitions)
executions = models.ForeignKey(Executions)
rest = models.ForeignKey(Rest)
class Meta:
verbose_name = 'Exercise'
verbose_name_plural = 'Workout 3'
def __str__(self):
return u'%s' % (self.exercise)
class Exercise4(models.Model):
card = models.ForeignKey(Card)
exercise = models.ForeignKey(Exercise)
series = models.ForeignKey(Series)
repetitions = models.ForeignKey(Repetitions)
executions = models.ForeignKey(Executions)
rest = models.ForeignKey(Rest)
class Meta:
verbose_name = 'Exercise'
verbose_name_plural = 'Workout 4'
def __str__(self):
return u'%s' % (self.exercise)
class Exercise5(models.Model):
card = models.ForeignKey(Card)
exercise = models.ForeignKey(Exercise)
series = models.ForeignKey(Series)
repetitions = models.ForeignKey(Repetitions)
executions = models.ForeignKey(Executions)
rest = models.ForeignKey(Rest)
class Meta:
verbose_name = 'Exercise'
verbose_name_plural = 'Workout 5'
def __str__(self):
return u'%s' % (self.exercise)
thanks for code, now it's more clearly.
In my opinion all your database structure ( created through django ORM models ) is incorrect, based on DRY and build database standards.
So I will show you how this database should looks for me. Only one more thing, you should using __unicode__ method instead of __str__ (link).
class Card - it's ok
class Exercise - it's provide only name field. why ? don't know, but I suggest to change the name of this class to ExerciseType, and I will tell you why later :)
Series, Repetitions, Executions, Rest - similar to Exercise model, provides only one field per model, and value of the each field is not very unique.
Exercise1-5 - name of the model should be Exercise, and has extra field named exercise_type, or type.
Look below:
class Card(models.Model):
number = models.IntegerField()
name = models.CharField(max_length=50)
surname = models.CharField(max_length=50)
trainer = models.CharField(max_length=50, blank=True, null=True)
#Card status
creation = models.DateField(auto_now_add=True)
expiration = models.DateField(blank=True, null=True)
#Member status
subscription = models.DateField(blank=True, null=True)
def __unicode__(self):
return u'%s %s' % (self.surname, self.name)
class Meta:
unique_together = (("number"),)
class ExerciseType(models.Model):
name = models.CharField(max_length=50)
def __unicode__(self):
return u'%s' % (self.name)
class Exercise(models.Model):
type = models.ForeignKey(ExerciseType)
card = models.ForeignKey(Card)
#instead of FK, better solutions is to use normal value-field
series = models.IntegerField()
repetitions = models.IntegerField()
executions = models.CharField()
rest = models.IntegerField()
#here comes methods like __unicode__ etc ....
So, as a result, we have 3 models ( tables ) instead of 11, much simpler sql query ( without 6 SQL joins. Functionality is the same ( I hope :) ).If you have any question, just ask me I will try to help.
hope this helps.