What does the built in class named list do? - list

I'm reading an OOP book and I'm at the inheritance chapter. There is a sample code that I don't understand. A class inherited a class named list but it wasn't defined. So I checked by typing list on my editor and it was blue. So that mean it is a class. I tried searching on Bing to see what the class did, but I only get documentations and tutorials on python list. Here's the code:
class ContactList(list):
def search(self, name):
'''Return all contacts that contain the search value in their name.'''
matching_contacts = []
for contact in self:
if name in contact.name:
matching_contacts.append(contact)
return matching_contacts
class Contact:
all_contacts = ContactList()
def __init__(self, name, email):
self.name = name
self.email = email
Contact.all_contacts.append(self)
print(self.all_contacts)
class Supplier(Contact):
def order(self, order):
print("If this were a real system we would send "
"'{}' order to '{}'".format(order, self.name))
Thanks!

Related

Django ModelForm field queryset based on another field

Consider my models.py,
PowerPolicy:
class PowerPolicy(models.Model):
name = models.CharField(max_length=15)
...
Group:
class Group(models.Model):
name = models.CharField(max_length=15)
#But then, we also have:
power_policies = models.ManytoManyField(PowerPolicy)
Player:
class Player(models.Model):
name = models.CharField(max_length=15)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
...
And then another model called,
UsePower:
class UserPower(models.Model):
player = models.ForeignKey(Player, on_delete=models.CASCADE)
power_policy = models.ForeignKey(PowerPolicy, on_delete=models.CASCADE)
...
But! Here's the catch: I want to make it so that my superuser (Note that my superuser isn't a player, he's simply a superuser) can only create a UsePower object of the Powers specified in the Player's Group. Now, I do know that I have to create a custom form and override the queryset of the power_policy field that returns, my the custom queryset according to my needs through a function.
- Here's what it would look something like:
class UsePowerForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UsePowerForm, self).__init__(*args, **kwargs)
def MyCustomFunctionThatReturnsTheQuerySet():
This function returns the Power policies that are allowed to the player in
their player Group. The only problem is,
Our little function here doesn't know how to get the player chosen.
could you help
return TheQuerySet
self.fields['power_policy'].queryset = MyCustomFunctionThatReturnsTheQuerySet()
And then use it on the Admin Site, by doing this:
class UsePowerAdmin(admin.ModelAdmin):
form = UsePowerForm
admin.site.register(UsePower, UsePowerForm)
I really hope this makes sense, and you guys could help me out.
Thank you for your time reading this, I honestly do appreciate it.
EDIT: Using form cleaning, or verifying during save, is not an option for me :(
You can get the player when the form is being initialized:
class UserPowerForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UsePowerForm, self).__init__(*args, **kwargs)
player = Player.objects.get(id=self.initial['player'])
###from here you can use player to get the power policies and put into list
self.fields['power_policy'] = forms.ChoiceField(choices=power_policy_list)
class Meta:
model = UserPower
fields = ['player', 'power_policy']

How to create a model instance object in Django without a form

New to django here. I am following this documentation link to create an instance of a model
https://docs.djangoproject.com/en/2.2/ref/models/instances/#creating-objects and I am missing something. Here is my code
#models.py
class Book(models.Model):
title = models.CharField(max_length=100)
#classmethod
def create(cls, title):
print('print title:')
print(title)
book = cls(title=title)
# do something with the book
return book
#forms.py
book = Book.create("Pride and Prejudice")
print('printing DJANGO--------------')
print(book)
#console output
print title:
Pride and Prejudice
printing DJANGO--------------
Book object (None)
I have literally copied the code from the tutorial and haven't changed a thing. What am I doing wrong?
Thanks
Everything is okay from my point of view. Just add book.save() and you'll see an id instead of None
If you want to change model's human readability, just add str() method to model
def __str__(self):
return self.title

override __str__(self) of a model from an imported app

I'm facing the following situation: I have a django project, which uses an outside app [App1]. Within App1, it has the following structure:
abstract class 'Base':
class Base(models.Model):
"""
Base model with boilerplate for all models.
"""
name = models.CharField(max_length=200, db_index=True)
alternate_names = models.TextField(null=True, blank=True,
default='')
..............
..............
class Meta:
abstract = True
def __str__(self):
display_name = getattr(self, 'display_name', None)
if display_name:
return display_name
return self.name
abstract class based on 'Base', called 'AbstractClassA':
class AbstractClassA(Base):
display_name = models.CharField(max_length=200)
....
....
class Meta(Base.Meta):
abstract = True
def get_display_name(self):
....
....
return ....
The non abstract class class ClassA(AbstractClassA)
Now, when I do a query in my view for this ClassA, for example:
qs = ClassA.objects.filter(Q(name__icontains=query_term)....)
return qs
I feed this qs into another outside app (autocomplete), so that when I type in 'xxxx' on my web form, the form would give me suggestions on available matches in the DB, based on this qs.
This all works great, the only thing is, the list of potential matches shown to me is the default representation of the ClassA objects, which I traced back to
def __str__(self):
display_name = getattr(self, 'display_name', None)
if display_name:
return display_name
return self.name
defined in the base abstract model I've mentioned earlier. What I want is, to have something else displayed as the list of potential matches (e.g. instead of 'display_name' or 'name', show me 'fieldA' + ';'+ 'fieldB' of each filtered item in qs).
My thought was to override this __str__ method somewhere. But because both the upstream and downstream aspect of my process are done in outside apps that I don't want to modify directly (i.e. copy directly into my Django project and rewrite certain parts), I'm not sure how I could achieve my goal.
Is there any elegant way to do so?
Please let me know if anything is unclear, or if I could provide you with any further information. Thanks!
Another approach besides Monkey Patching is to use Proxy models.
class MyClassA(ClassA):
class Meta:
proxy = True
def __str__(self):
return self.attribute
Then use MyClassA instead of ClassA.
From your question it is not clear if the non-abstract classes are written by you, but what you can do is to create a mixin and add that to the class signature of your concrete classes, such as:
class NiceStrMixin():
def __str__(self):
return self.display_name
then
class ClassA(AbstractClassA, NiceStrMixin):
...
If you don't have access to ClassA either, you can monkey patch AbstractClassA.

What do multiple parameters of class MyModel(..., models.Model) beside models.Model in Django mean?

class Post(AnoterModelMixin, AANotherModelMixin, models.Model):
What does this mean if it's in models.py for django?
Practically, it's a really convenient way of organizing your code. A mixin is a special kind of multiple inheritance.
AnoterModelMixin can contain a set of methods that you can use on your model; these are inherited:
class Post(AnoterModelMixin, AANotherModelMixin, models.Model):
name = models.CharField(max_length=150)
AnoterModelMixin could look like this:
class AnoterModelMixin(object):
"""Additional methods on the Post model"""
def get_short_name(self):
"""Returns the first 10 characters of the post name"""
return self.name[:10]
def get_longer_name(self):
"""Returns the first 15 characters of the post name"""
return self.name[:15]
You can then use it like so:
demo_post = Post.objects.create(name='This is a very long post name')
demo_post.get_short_name() # 'This is a '
demo_post.get_longer_name() # 'This is a very '

problem with filtering in a referenceproperty dropdown - Django

I have the following problem. I have a contact class that different
users can tag with their own topics:
class Contact(db.Model):
contact_date = db.DateProperty(auto_now_add=True)
remarks = db.TextProperty()
topic = db.ReferenceProperty(Topic)
class Topic(db.Model):
topic = db.StringProperty(required=True)
description = db.TextProperty()
owner = db.ReferenceProperty(User, collection_name='topic_set')
def __unicode__(self):
return '%s' % (self.topic)
In the form for this i want to only show the Topics for a certain user
class ContactForm(forms.ModelForm):
def __init__(self, user_filter, *args, **kwargs):
self.base_fields['topic'].queryset = Topic.all().filter('owner
= ', user_filter)
super(ContactForm, self).__init__(*args, **kwargs)
I then call the ContactForm from the view as follows:
form = ContactForm(user_filter = request.user.key())
This all works as expected. However when I submit the form I get:
Caught an exception while rendering: Unsupported type for property :
<class 'django.http.QueryDict'>
Am I doing something wrong? Is this some problem with appengine django
implementation?
Peter
A Contact can have one Topic and one Topic only. As you explained:
I have a contact class that different users can tag with their own topics
I would move the ReferenceProperty to the Topic class:
class Topic(db.Model):
contact = db.ReferenceProperty(Contact)
Now one Contact can have multiple Topics.
Your exception comes from assigning a property with a Request Query Dictionary. This probably comes from declaring user_filter as an argument, but using it as a keywords argument.
It should be:
form = ContactForm(request.user.key())
But as stated above, first you should revise your models.