Django documentation reference - python

I am quite new to Django and I really don't get the documentation. For example in my code I query all available pages with Page.objects.public(). This gives me objects of type cms.models.pagemodel.Page. To use this in a template I need to know which methods I can use on this but I just cannot find the documentation and I cannot believe that I have to browse the Django source code to get to know the interface.
So does anyone know where I can find the available methods?

The Django model instance reference has some helpful stuff, but generally when working with model instances, we tend to access their data as attributes (which will be in the model definition) and we call the save method after updating these attributes.
The data types you'll get back from Django model instance attributes are all going to be Python objects, so it's usually more important to understand how to interact with those than to understand all the methods available on an instance.
To get to know a Django model, you should look at its definition. Here's an example:
class Page(models.model):
publication_date = models.DateTimeField(null=True)
name = models.CharField(max_length=255, blank=True)
For example, here, if you had a Page object with a publication_date, and that attribute was stored as a DateTimeField, then Django is going to give you a datetime object when you do:
>>> page = Page.objects.first()
>>> pubdate = page.publication_date
>>> type(pubdate)
<type 'datetime.datetime'>
Similarly, the name attribute is simply a Python string:
>>> page.name = "New page name"
>>> page.save()
# New page name is stored in the db and will be there when queried next.
Lastly, to output these things in a template, you would just refer to them in the same way:
Assuming you have a `page` variable here that is an instance...
Page Name is: {{ page.name }}
The Django book may be more helpful to familiarize yourself with interacting with Django models.

Related

Django ._meta and adding to ManyToMany fields

I haven't had much luck finding other questions that helped with this, but apologies if I missed something and this is a duplicate.
I'm trying to add to some ManyToMany fields, without having to explicitly type out the names of the fields in the code (because the function I'm working on will be used to add to multiple fields and I'd rather not have to repeat the same code for every field). I'm having a hard time using ._meta to reference the model and field objects correctly so that .add() doesn't throw an "AttributeError: 'ManyToManyField' object has no attribute 'add'".
This is simplified because the full body of code is too long to post it all here, but in models.py, I have models defined similar to this:
class Sandwich(models.Model):
name = models.CharField(max_length=MAX_CHAR_FIELD)
veggies = models.ManyToManyField(Veggie)
meats = models.ManyToManyField(Meat)
class Veggie(models.Model):
name = models.CharField(max_length=MAX_CHAR_FIELD)
class Meat(models.Model):
name = models.CharField(max_length=MAX_CHAR_FIELD)
Once instances of these are created and saved, I can successfully use .add() like this:
blt = Sandwich(name='blt')
blt.save()
lettuce = Veggies(name='lettuce')
lettuce.save()
tomato = Veggies(name='tomato')
tomato.save()
bacon = Meat(name='bacon')
bacon.save()
blt.veggies.add(lettuce)
blt.veggies.add(tomato)
blt.meats.add(bacon)
But if I try to use ._meta to get blt's fields and add to them that way, I can't. ie something like this,
field_name='meats'
field = blt._meta.get_field(field_name)
field.add(bacon)
will throw "AttributeError: 'ManyToManyField' object has no attribute 'add'".
So, how can I use ._meta or a similar approach to get and refer to these fields in a way that will let me use .add()? (bonus round, how and why is "blt.meats" different than "blt._meta.get_field('meats')" anyway?)
Why do you want to do
field = blt._meta.get_field(field_name)
field.add(bacon)
instead of
blt.meats.add(bacon)
in the first place?
If what you want is to access the attribute meats on the blt instance of the Sandwich class because you have the string 'meats' somewhere, then it's plain python you're after:
field_string = 'meats'
meats_attribute = getattr(blt, field_string, None)
if meats_attribute is not None:
meats_attribute.add(bacon)
But if your at the point where you're doing that sort of thing you might want to revise your data modelling.
Bonus round:
Call type() on blt.meats and on blt._meta.get_field(field_name) and see what each returns.
One is a ManyToManyField, the other a RelatedManager. First is an abstraction that allows you to tell Django you have a M2M relation between 2 models, so it can create a through table for you, the other is an interface for you to query those related objects (you can call .filter(), .exclude() on it... like querysets): https://docs.djangoproject.com/en/4.1/ref/models/relations/#django.db.models.fields.related.RelatedManager

Default relation for Django OneToOne Field

I'm trying to create a couple django models with a one to one relation. However I'm trying to get it so the related one to one model is automatically created. If I have something simple like this:
class MyObject(models.Model):
data = models.OneToOneField('MyData', related_name='my_object')
class MyData(models.Model):
info = models.TextField(null=True)
If I create a MyObject and access MyObject.data it will return None. I was hoping there was a way I can have it return a MyData object (just default reference).
I'd like MyObject to automatically have a related MyData object. Is there a way for me to do this or do I need to check every time to see if there's a related MyData object?
Have you seen the official doc?
d = MyData(info='whatever')
o = MyObject(data=d)
How can it be automatic if info text field has to be filled in?
after seeing your edit:
you can probably set my data to be null
o = MyObject(data=Mydata(info=None))
of course, your Mydata should now be able to accept None as their type.

What is happening when attributes are applied to a class method in python?

I have been learning python and django and building a simple blog as a test.
I have Django admin running and working fine, and was trying to modify the admin classes to introduce an image thumbnail into the list view.
Using the example in the Django documentation, I have got the thumbnail working using the following in my admin class:
class ImageAdmin(admin.ModelAdmin):
list_display = ('thumbnail', "name", "created")
def thumbnail(self, image):
return '<img src="%s" alt="%s" width="100px" />' % (image.url, image.name)
thumbnail.short_description = "Thumbnail"
thumbnail.allow_tags = True
thumbnail.admin_order_field = "name"
It all works just fine, but I don't understand fully what the method definition for ImageAdmin.thumbnail is doing, where it appears to be adding properties to the method. So I was hoping someone could help explain it to me.
In Python, class methods themselves are objects, and you can set attributes (not, strictly speaking, properties - property has a specific meaning in Python) on them. These attributes are then available to anything that can access the method - Django will check foo.thumbnail.allow_tags to see if it should escape the results of calling foo.thumbnail().
There are some subtleties - bound instance methods don't allow setting attributes, so you can't actually assign to foo.thumbnail.allow_tags. But doing it at the class level works fine.
For a full description, check out PEP 232.
The method thumbnail is called to display the value. Django allows you to set attributes on it which are used for other purposes, such as the name in the admin (thumbnail.short_description = "Thumbnail"). So both the method and the properties that are set on it are used.

Django Mongodb ListField not saving or updating

I am starting to create a webapp using Django and MongoDB. Everything is working fine when I create a model and save it into the Database. Now, I do a "Class.objects.get()" to get the object I need from my DB and I have one field called "media" which is a ListField(). I had tried doing either:
Concert.media.append(list)
or
Concert.media.extend(list)
and then
Concert.save()
This is my "Concert" object in my models.py:
class Concert(models.Model):
main_artist = models.CharField(max_length=50)
concert_id = models.AutoField(primary_key=True)
openers = ListField(EmbeddedModelField('Opener'))
concert_date = models.DateField()
slug = models.SlugField(unique=True)
media = ListField()
And when I go to see the results in does not update the object. No values where saved. If someone can help me I going to give a super cyber fist bump.
Concert is a class, not an instance. You can't save a class. You need to make an instance of the class and save that. Something like
c = Concert()
c.media.append(list)
c.save()
(btw, just as a note, list is a bad variable name because list is a type in python. Never use types as variable names (though everyone is guilty of this at one point or another, including me.))

Need some explanation regarding BaseCommentAbstractModel of django comment app

class BaseCommentAbstractModel(models.Model):
"""
An abstract base class that any custom comment models probably should
subclass.
"""
# Content-object field
content_type = models.ForeignKey(ContentType,
verbose_name=_('content type'),
related_name="content_type_set_for_%(class)s")
object_pk = models.TextField(_('object ID'))
content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk")
# Metadata about the comment
site = models.ForeignKey(Site)
class Meta:
abstract = True
def get_content_object_url(self):
"""
Get a URL suitable for redirecting to the content object.
"""
return urlresolvers.reverse(
"comments-url-redirect",
args=(self.content_type_id, self.object_pk)
)
I have two questions related to this model code.
models.TextField(_('object ID')) Object ID which probably is the verbose Name of this TextField ,How does it reflect in the database?
Why do Django relies on field abstract of Meta innerclass instead of using abc(AbstractBaseClass) module?
That is indeed that verbose name. I assume you understand that _ is the call to ugettext_lazy which is for localizing strings. This is the verbose name of the field. The verbose name is not represented in the database. The name of the field in the database would be object_pk.
I'm not a django dev so I can't speak with authority, but some things are obvious. ABC is new in Python 2.6. This is an issue because as of the most recent release the minimum python version was finally moved to 2.5. This has been being bumped quite quickly as of late. For example it was only on django 1.2 that python 2.4 became required. Abstract models have existed at least as far back as django 1.0 and I think even further back then that (though I can't recall for sure) So even if ABC would be suitable (which I'm not sure it is since the behavior of models is kinda complex), it wouldn't be suitable for django at this point due to the required python version.
Additionally there is some complexity in managing classes that represent the database rather than just data structures. I'm not sure how much this impacts abstract models but for example you can't perform field hiding on django attributes that are Field instances.

Categories