Use of unicode in Django - python

Why is a unicode function required in models.py?
i.e,
def __unicode__(self)
return sumid;

It's not. If you define a __unicode__() method, Django will call it when it needs to render an object in a context where a string representation is needed (e.g. in the model's admin pages).
The documentation says:
The __unicode__() method is called
whenever you call unicode() on an
object. Since Django's database
backends will return Unicode strings
in your model's attributes, you would
normally want to write a __unicode__()
method for your model.

I'm a bit new to Django, but I think I can help you.
First, it isn't exactly required, but it's a really good idea. The field is used to create representations of your objects in the Django admin (otherwise they all have the same name :-P) and when you print out an object to your terminal window to see what's going on (otherwise you get a generic mostly useless message).
Second, from what you wrote, it looks like you're new to Python. I recommend reading some Python tutorials on class syntax. Also, semicolons aren't necessary in this language. The correct syntax for creating the unicode method is:
class Foo(models.Model):
# Model fields go here
def __unicode__(self):
return u"%i" % self.sumid
The __unicode__ method has double underscores because it is a special function, namely when the builtin function unicode( obj ) is called on it, it returns a unicode string representation of that object (sort of like java's ToString).
I hope this helps :-)

I think the others have given some detailed explanations that should be more than enough for you. But here's a straightforward answer: __unicode__() is equivalent to toString() in Java (and many other languages)

Related

Django: How to add to an ArrayField?

I have some questions about the ArrayField mentioned here: https://docs.djangoproject.com/en/3.1/ref/contrib/postgres/fields/#django.contrib.postgres.fields.ArrayField
How do you add to an ArrayField? It's clear you can treat it like a regular field and do things like
my_array_field = []
my_array_field.save()
But what's confusing is I'm seeing everyone mention my_array_field.append("something") in StackOverflow questions. This isn't mentioned in the documentation at all. Moreover, if an arrayfield is .append()ed to, does it still require .save()?
do we need to call save()?
Yes, we need to call the save() method to COMMIT the changes to Database. Unless calling the save() method, the value only persists in the scope of the variable, as the python list. So, calling the save() is a must do thing while updating the values.
how to add values to array field?
You can treat it as a normal python list object, because Django converts the db array field to native Python list object
model_instance.my_array_field = [1,2,3]
model_instance.save()
model_instance.my_array_field += [4,5,6]
model_instance.save()
This isn't mentioned in the documentation
Probably, they may be missed to include this information.
Django documentation ArrayField
recommends to add some default value, and make it callable, so just try in your models:
class SomeModel(models.Model):
...
my_array_field = ArrayField(models.CharField(max_length=255), default=list)
So you'll be able to add items in it just like with regular list in python:
my_array_field.append("something")
my_array_field.append("another_something")
And even more - you can use all methods like pop, extend, index etc.

Get Python type of Django's model field?

How can I get corresponding Python type of a Django model's field class ?
from django.db import models
class MyModel(models.Model):
value = models.DecimalField()
type(MyModel._meta.get_field('value')) # <class 'django.db.models.fields.DecimalField'>
I'm looking how can I get corresponding python type for field's value - decimal.Decimal in this case.
Any idea ?
p.s. I've attempted to work around this with field's default attribute, but it probably won't work in all cases where field has no default value defined.
I don't think you can decide the actual python type programmatically there. Part of this is due to python's dynamic type. If you look at the doc for converting values to python objects, there is no hard predefined type for a field: you can write a custom field that returns object in different types depending on the database value. The doc of model fields specifies what Python type corresponds to each field type, so you can do this "statically".
But why would you need to know the Python types in advance in order to serialize them? The serialize modules are supposed to do this for you, just throw them the objects you need to serialize. Python is a dynamically typed language.
An ugly alternative is to check the field's repr():
if 'DecimalField' in repr(model._meta.get_field(fieldname)):
return decimal.Decimal
else:
...
However, you have to this for all types seperatly.

In Django, why do I need __unicode__?

I'm starting to learn Django and I'm starting out with the Django book.
I came across this concept and I have a hard time understanding the logic..
The book says
"Django uses Unicode objects throughout the framework. Model objects are retrieved as Unicode objects, views interact with Unicode data, and templates are rendered as Unicode. Generally, you won’t have to worry about making sure your encodings are right; things should just work."
Then why do you need to do "def unicode()" to print in unicode? Shouldn't it just work with plain vanilla print()?
Have you tried just printing a model instance that doesn't have a __unicode__ method? You don't get anything really useful. That's where __unicode__ comes into play. You get to define how your model instances are displayed whenever you try to use them in a unicode context.
Try this experiment. Create a simple model. Now print it out:
class MyModel(models.Model):
name = models.CharField(max_length=20)
>>> obj = MyModel("foo")
>>> print obj
See what you get. Now add a __unicode__() method.
class MyModel(models.Model):
name = models.CharField(max_length=20)
def __unicode__(self):
return self.name
Run it again:
>>> obj = MyModel("foo")
>>> print obj
Did you read https://docs.djangoproject.com/en/dev/ref/models/instances/#unicode ? It explains why we needs unicod well. Because python 2.x is not using unicode basically, django needs to handle unicode.

Python model object validation

I'm writing an interface to be used by two applications. This interface should use some DoSomethingRequest and DoSomethingResponse classes to do the communication.
Is there any library that does some model validation, for example like Django's Model?
I basically want to be able to say something like:
Object A must have a "text" property of type str(), a "number" property of type int(), an "items" property of type list(). In a DRY way.
I'm looking for something like the following, or better:
class MyEmbeddedModelClass(EmbeddedModel):
text = TextField(required = True)
class MyModel(Model):
text = TextField(required = True)
number = IntField(default = 0)
items = ListField(EmbeddedModel)
a = MyModel()
a.text = "aaaa"
a.number = 1
a.items = [
MyEmbeddedModelClass("bbbb"),
MyEmbeddedModelClass("cccc"),
MyEmbeddedModelClass("dddd")
]
a.validate()
I know I can write my own, but I'd rather use a library if available, I'm a bit new to this.
If you want to enforce interfaces, or use design-by-contract, then you probably want the zope.interface library. Despite the name, which reflects its origins in Zope, it's not actually tied to that framework at all and is quite usable outside.
I think decorators could be used for this.
check this link
Combining Descriptors with Class Decorators for Validation
For a different approach check Duck typing
Because python is dynamic, the convention is to require an object to behave like an instance of a particular class rather than enforce a specific type.
Somewhere in your code, preferably at the point where you need to access those properties, but as early as possible assert that the object has those properties and further assert that those properties are what you expect them to be.
This raises an AssertionError exception if the object o, regardless of type, if it is missing the 'someattribute' attribute:
assert(hasattr(o, 'someattribute'))
Further, if o.someattribute is not a string:
assert(isinstance(o.someattribute, basestring))

How do I get the key value of a db.ReferenceProperty without a database hit?

Is there a way to get the key (or id) value of a db.ReferenceProperty, without dereferencing the actual entity it points to? I have been digging around - it looks like the key is stored as the property name preceeded with an _, but I have been unable to get any code working. Examples would be much appreciated. Thanks.
EDIT: Here is what I have unsuccessfully tried:
class Comment(db.Model):
series = db.ReferenceProperty(reference_class=Series);
def series_id(self):
return self._series
And in my template:
more
The result:
more
Actually, the way that you are advocating accessing the key for a ReferenceProperty might well not exist in the future. Attributes that begin with '_' in python are generally accepted to be "protected" in that things that are closely bound and intimate with its implementation can use them, but things that are updated with the implementation must change when it changes.
However, there is a way through the public interface that you can access the key for your reference-property so that it will be safe in the future. I'll revise the above example:
class Comment(db.Model):
series = db.ReferenceProperty(reference_class=Series);
def series_id(self):
return Comment.series.get_value_for_datastore(self)
When you access properties via the class it is associated, you get the property object itself, which has a public method that can get the underlying values.
You're correct - the key is stored as the property name prefixed with '_'. You should just be able to access it directly on the model object. Can you demonstrate what you're trying? I've used this technique in the past with no problems.
Edit: Have you tried calling series_id() directly, or referencing _series in your template directly? I'm not sure whether Django automatically calls methods with no arguments if you specify them in this context. You could also try putting the #property decorator on the method.

Categories