Value of a field by default Django Admin - django

I have the following model
class Trivias(models.Model):
GIFT_CHOICES = (
('gas', 'Gasolina'),
('money', 'Dinero'),
('xp','Experiencia'),
)
NUMQ_CHOICES = (
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
)
idtrivias = models.IntegerField(primary_key=True)
url = models.CharField(max_length=450)
numQ = models.IntegerField(max_length=4,choices=NUMQ_CHOICES)
idtipospropiedades = models.ForeignKey(Tipospropiedades, db_column='idtipospropiedades')
idtitulos = models.ForeignKey(Titulos, db_column='idtitulos')
correct = models.IntegerField(max_length=1)
gift = models.CharField(max_length=5,choices=GIFT_CHOICES)
value = models.CharField(max_length=20)
class Meta:
db_table = u'trivias'
I want the url field has a default value in the Django Admin, How I can do?
regards

Is there any reason you're storing the URL as a CharField rather than a URLField? URLField is a URL-specific subclass of CharField. Also, to set default values, use default="x", e.g.
url = models.URLField(default='http://www.foo.com')
Hope that helps.

Related

How can I calculate avg of data from django form and store in variable for later use?

In the readerpage function, in my views.py, I am trying to calculate the avg of the two variables: readability_rating and actionability_rating, and store the result in avg_rating
def readerpage(request, content_id):
content = get_object_or_404(Content, pk=content_id)
form = ReviewForm(request.POST)
if form.is_valid():
review = form.save(commit=False)
review.content = content
readability_rating = form.cleaned_data['readability_rating']
readability = form.cleaned_data['readability']
actionability_rating = form.cleaned_data['actionability_rating']
actionability = form.cleaned_data['actionability']
general_comments = form.cleaned_data['general_comments']
review.avg_rating = (float(readability_rating) +
float(actionability_rating)) / 2
review.save()
return redirect('home')
args = {'content': content, 'form': form}
return render(request, 'content/readerpage.html', args)
The problem is that with this setup the two variables are still ChoiceFields - as such the above setup gives me the error:
float() argument must be a string or a number, not 'ChoiceField'
I’ve tried converting them to floats without any luck.
I also attempted using the TypedChoiceField with coerce=float, still with no luck
I’m not sure whether the best place to calculate this is in my function, my form, or my model?
models.py:
class Review(models.Model):
content = models.ForeignKey(Content, null=True, on_delete=models.CASCADE)
readability = models.CharField(null=True, max_length=500)
readability_rating = models.IntegerField(null=True)
actionability = models.CharField(null=True, max_length=500)
actionability_rating = models.IntegerField(null=True)
general_comments = models.CharField(null=True, max_length=500)
avg_rating = models.FloatField(null=True)
def _str_(self):
return self.title
forms.py:
class ReviewForm(forms.ModelForm):
readability = forms.CharField(widget=forms.Textarea)
readability_rating = forms.ChoiceField(
choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)])
actionability = forms.CharField(widget=forms.Textarea)
actionability_rating = forms.ChoiceField(
choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)])
general_comments = forms.CharField(widget=forms.Textarea)
class Meta:
model = Review
fields = ['readability', 'readability_rating',
'actionability', 'actionability_rating', 'general_comments']
Thanks for reading this.
The variables are ChoiceFields because you are declaring them as ChoiceFields in view function. Shouldn't you just fetch the values from your cleaned_data?
readability_rating = form.cleaned_data['readability_rating']
And to the second part of your question: Why not add it as a #property to your model?

get long name during annotate in django ORM query

I have this model:
class Rank(models.Model):
RANK_TYPE_CHOICES = (
('O', 'Officer'),
('E', 'Enlisted'),
('V', 'Civilian'),
('C', 'Cadet'),
)
ShortName = models.CharField(max_length=50)
LongName = models.CharField(max_length=500)
Type = models.CharField(max_length=1, choices=RANK_TYPE_CHOICES, default='O')
Genre = models.ForeignKey(Genre, on_delete=models.DO_NOTHING)
Career = models.ForeignKey(Career, on_delete=models.DO_NOTHING)
image = models.ForeignKey(Photos, on_delete=models.DO_NOTHING)
when I perform this ORM action:
models.Rank.objects.values('Type').annotate(total=Count('Type')).order_by()
I get this response
<QuerySet [{'Type': 'O', 'total': 1}]>
Exactly as I want.
However, as you can see, it gives me the short type. How do I make it show the long name instead of the type choice short name?
Thanks.
You will need to add the values manually.
rank_dict = dict(RANK_TYPE_CHOICES)
for obj in my_ranks:
obj['full_type'] = rank_dict[obj['Type']]

Display forms choice in template-Django

On the template, when I call person.health_issue, I am getting '1','2' instead of 'Abdominal pain','Anaphylaxis'. How to display the value ('Abdominal pain','Anaphylaxis') instead of the code(1 or2 etc).
I tried with this also {{ person.get_health_issue_display }} in template,it is not displayed anything.
forms.py
HEALTH_USSUES = (
('1', 'Abdominal pain'), ('2', 'Anaphylaxis'), ('3', 'Asthma'),
('4', 'Bruising'), ('5', 'Chest pains'), ('6', 'Coughs or Colds')
)
class PersonActionsForm(forms.ModelForm):
action = forms.MultipleChoiceField(widget=forms.Select(), choices=HEALTH_USSUES, required=False)
models.py
class ReportPerson(models.Model):
report = models.ForeignKey(Report)
name = models.CharField('Name', max_length=100)
first_aid = models.BooleanField('First aid', default=False)
health_issue = models.IntegerField(default=0)
views.py
def report_template(request):
""""""
person = ReportPerson.objects.get(pk=person_id)
""""""
return render(request, 'event/print.html',
{
'person':person
})
can any one tell me how to do this.
Thanks
As you don't have any choices set in model field health_issue you need to write the get_health_issue_display method by your self i will name it as health_issue_display so that default get_FOO_display method not gets overridden:
HEALTH_USSUES = (
(1, 'Abdominal pain'), (2, 'Anaphylaxis'), (3, 'Asthma'),
(4, 'Bruising'), (5, 'Chest pains'), (6, 'Coughs or Colds')
)
class ReportPerson(models.Model):
report = models.ForeignKey(Report)
name = models.CharField('Name', max_length=100)
first_aid = models.BooleanField('First aid', default=False)
health_issue = models.IntegerField(default=1)
def health_issue_display(self):
for c in HEALTH_USSUES:
if c[0] == self.health_issue:
return c[1]
Or just add choices in the model field:
health_issue = models.IntegerField(default=1, choices=HEALTH_USSUES)
Now you have get_health_issue_display.
Also make the first value in every choice as integer (1, 'Abdominal pain') rather than string '1'. Just to remove the confusion.
You have default=0 which does not exists in choices. Change it to default=1

Return choices in model

I have a model:
class Detail(models.Model):
types_choices = (
(1, 'Sport'),
(2, 'Turbo'),
(3, 'Turbo++'),
)
car = models.ForeignKey(Car)
d_type = models.PositiveIntegerField(choices=types_choices, max_length=1)
def __unicode__(self):
return u"%s, %s" % (self.car.name, types_choices[self.d_type][1])
In admin interface there is a error: global name 'types_choices' is not defined. I think it about my return. How to fix it? I need car name and 'sport'(or turbo, etc.) in one string in admin interface.
Thanks.
you forgot the self.
class Detail(models.Model):
types_choices = (
(1, 'Sport'),
(2, 'Turbo'),
(3, 'Turbo++'),
)
car = models.ForeignKey(Car)
d_type = models.PositiveIntegerField(choices=types_choices, max_length=1)
def __unicode__(self):
return u"%s, %s" % (self.car.name, self.types_choices[self.d_type][1])
You should use self.get_d_type_display().
You should use self.types_choices. This is because types_choices is a property on your
Detail class.
Django docs have a good pattern on how to use choices: https://docs.djangoproject.com/en/dev/ref/models/fields/#choices
You can also use self.get_d_type_display() to get the verbose name of the choice field.

Django use only some fields in ForeignKey

I have three classes
Class Company(models.Model):
name = CharField( max_length = 26 , blank = True)
#(...)
class Person(models.Model):
name = CharField( max_length = 26 , blank = True)
function = CharField( max_length = 50 , blank = True)
company = ForeignKey ( Company , related_name = 'persons' )
# All the company table inside the data base is loaded in order to make the query,
# This make a HUGE amount of data and takes too many time...
# (...)
def __unicode__(self):
# caption uses both name and company__name fields but no other fields
return self.name + '(' + self.company.name + ')'
class Contact(models.Model):
person = ForeignKey ( Person )
In order to optimise performances, I would like the latest person field to use
Person.objects.all().only('name', 'company__name')
as queryset. Is it possible?
You can use values method, which return a subclass of QuerySet called ValuesQuerySet.
Person.objects.all().values('name', 'company__name')
For more information Django Doc
Use proxy models :
class Person_short_manager(Manager):
def get_query_set(self):
return super(self, Person_short_manager).get_query_set().only('name','company__name')
class Person_short(Person):
objects = Person_short_manager(Manager)
class Meta:
proxy = True
then replace
person = ForeignKey ( Person )
by
person = ForeignKey ( Person_short )