The code is short and simple:
class Contact:
all_contacts = []
def __init__(self, name, email):
self.name = name
self.email = email
Contact.all_contacts.append(self)
c1 = Contact("Paul", "something#hotmail.com")
c2 = Contact("Darren", "another_thing#hotmail.com")
c3 = Contact("Jennie", "different#hotmail.com")
for i in Contact.all_contacts:
print(i)
Clearly all I want to do is print the 'all_contacts' list with the info I have added, but what I get is:
<__main__.Contact object at 0x2ccf70>
<__main__.Contact object at 0x2ccf90>
<__main__.Contact object at 0x2ccfd0>
What am I doing wrong?
Add the following to your Contact class:
class Contact:
...
def __str__(self):
return '%s <%s>' % (self.name, self.email)
This will tell Python how to render your object in a human-readable string representation.
Reference information for str
The __repr__ and __str__ methods for Contact aren't defined, so you get this default string representation instead.
def __str__(self):
return '<Contact %s, %s>' % (self.name, self.email)
Separate the container from the items stored in the container.
Add a __str__() method to Contact.
class Contact:
def __init__(self, name, email):
self.name = name
self.email = email
def __str__(self):
return "{} <{}>".format(self.name, self.email)
class ContactList(list):
def add_contact(self, *args):
self.append(Contact(*args))
c = ContactList()
c.add_contact("Paul", "something#hotmail.com")
c.add_contact("Darren", "another_thing#hotmail.com")
c.add_contact("Jennie", "different#hotmail.com")
for i in c:
print(i)
Related
Am trying to write update view,but got an error please help me to find the problem,thanks :)
At first I have many to many field in my model.It is my model
class Portfolio(models.Model):
name = models.CharField(max_length=50, unique=True, blank=False, null=True)
market = models.ForeignKey(Market, on_delete=models.DO_NOTHING, related_name='market')
investor = models.ForeignKey('accounts.User', on_delete=models.DO_NOTHING, related_name='investor')
assets = models.ManyToManyField(Assets, related_name='assets')
def __str__(self):
return self.name
After that I have a serializer for my view:
class PortfolioSerializer(serializers.ModelSerializer):
class Meta:
model = Portfolio
fields = ['name', 'market', 'investor', 'assets']
And it's my view:
class PortfolioUpdateView(APIView):
serializer_class = PortfolioSerializer
def put(self, request, *args,):
data = request.data
portfo = Portfolio.objects.get(id=id)
print(portfo)
serilize = self.serializer_class(instance=request.user, data=request.POST)
if serilize.is_valid():
name = serilize.data['name']
market = Market.objects.get(pk=int(request.POST.get('market', '')))
assets = Assets.objects.get(pk=int(request.POST.get('assets', '')))
Portfolio.objects.update(name=name, market=market,
assets=assets,
)
return portfo
else:
pass
and at the end it is my error:
TypeError at /market/update/1
put() got an unexpected keyword argument 'id'
I found the answer by my self,because I needed to use id for get obj so I used request.data that is body's data of object include obj's id and added query-set method for getting the class objs
class PortfolioUpdateView(viewsets.ModelViewSet):
serializer_class = PortfolioSerializer
def get_queryset(self):
portfolio = Portfolio.objects.all()
return portfolio
def put(self, request, *args, **kwargs):
data = Portfolio.objects.get(id=request.data['id'])
update_portfolio = Portfolio.objects.update(name=data['name']
, market=Market.objects.get(pk=int(request.POST.get('market', ''))))
update_portfolio.save()
for asset in data['assets']:
asset_obj = Assets.objects.update(asset_name=asset['asset_name'])
update_portfolio.assets.add(asset_obj)
serializer = PortfolioSerializer(update_portfolio)
return Response(serializer.data)
And this is the URL
router.register("update", PortfolioUpdateView, basename="update")
I am programming an application where I want to store Session information by a UUID. For this purpose, I wrote this code:
import uuid
class ObjectStore:
def __init__(self):
self.objects = {}
def add(self, obj):
uuid_value = uuid.uuid4() # UUID4 generates a random UUID
self.objects[uuid_value] = obj
return uuid_value
def retrieve(self, uuid):
return self.objects[uuid]
Is this structure a common pattern? If so, does it have a name?
I'm trying to found how Restframework's permission work , so i try write some code that response a simple Json. But the existence or absence of a ā€¨permission_classes does not affect the execution of the code and endpoint will response all request without checking any permission.
here is my code:
class TeacherStatisticPost(generics.RetrieveAPIView):
permission_classes = (ClassOwnerPermission)
queryset = ClassRoom.objects.all()
lookup_field = "id"
lookup_url_kwarg = 'classRoom_id'
def get_klass(self):
class_id = self.kwargs['classRoom_id']
return ClassRoom.objects.get(id=classRoom_id)
def get(self, request, *arg, **kwargs):
klass = self.get_klass()
response ={
'class_room_grade' : klass.grade,
'class_room_name' : klass.name,
}
return JsonResponse(response, safe=False)
and here is my permission.py:
class ClassOwnerPermission(permissions.BasePermission):
def has_perm(self, user, klass):
print("now in class perm") # never print out any thing!
return klass.owner == user
def has_object_permission(self, request, view, obj): # where is come from 'obj' ?
return self.has_perm(request.user, obj)
im try to set permission that just owner of ClassRoom can access to this endpoint.
Firstly, DRF expects permission_classes to be list or tuple. permission_classes at the line permission_classes = (ClassOwnerPermission) is not neither tuple not list. Put comma after the ClassOwnerPermission.
The line permission_classes = (ClassOwnerPermission, ) should work.
Secondly, you do not use get_object method which checks the permissions. Remove def get_klass(self): method and use get_object
Your view should look like following:
class TeacherStatisticPost(generics.RetrieveAPIView):
permission_classes = (ClassOwnerPermission, )
queryset = ClassRoom.objects.all()
lookup_field = "id"
lookup_url_kwarg = 'classRoom_id'
def get(self, request, *arg, **kwargs):
klass = self.get_object()
response ={
'class_room_grade' : klass.grade,
'class_room_name' : klass.name,
}
return JsonResponse(response, safe=False)
I'm not understanding how to use custom fields in a ConnectionField in graphene. I have something like:
class ShipConnection(Connection):
extra = String()
class Meta:
node = Ship
SHIPS = ['Tug boat', 'Row boat', 'Canoe']
class Query(AbstractType):
ships = relay.ConnectionField(ShipConnection)
def resolve_ships(self, args, context, info):
return ShipConnection(
extra='Some extra text',
edges=???
)
Normally, you'd say:
def resolve_ships(self, args, context, info):
return SHIPS
but how do you return something in extra and return a list?
The answer turns out to be to use an undocumented class method of graphene's ConnectionField class, called resolve_connection. The following works:
def resolve_ships(self, args, context, info):
field = relay.ConnectionField.resolve_connection(
ShipConnection,
args,
SHIPS
)
field.extra = 'Whatever'
return field
The proper way to do this is exactly explained here.
class Ship(graphene.ObjectType):
ship_type = String()
def resolve_ship_type(self, info):
return self.ship_type
class Meta:
interfaces = (Node,)
class ShipConnection(Connection):
total_count = Int() # i've found count on connections very useful!
def resolve_total_count(self, info):
return get_count_of_all_ships()
class Meta:
node = Ship
class Edge:
other = String()
def resolve_other(self, info):
return "This is other: " + self.node.other
class Query(graphene.ObjectType):
ships = relay.ConnectionField(ShipConnection)
def resolve_ships(self, info):
return get_list_of_ships_from_database_or_something_idk_its_your_implmentation()
schema = graphene.Schema(query=Query)
I don't know if this is recommended, but the resolve_total_count method can also be implemented as:
def resolve_total_count(self, info):
return len(self.iterable)
I don't know if the iterable property is documented anywhere, but I was able to find it while investigating the Connection class
I've got a model that references another model via OneToOneField so that when you use Django's built-in delete_selected admin action, the associated model's data is not deleted. I'd like to write a custom admin action to delete the data in that associated model as well.
Here's my model:
class Party(models.Model):
TYPE_CHOICES=(
('P','Person'),
('O','Organization')
)
partyType = models.CharField(max_length=1, choices=TYPE_CHOICES)
name = models.CharField(max_length=100)
comment = models.CharField(max_length=500,blank=True)
accessIdCrossRef=models.IntegerField(blank=True, null=True)
mailingLists = models.ManyToManyField(MailingList)
inMainList=models.BooleanField(default=False)
inSubList=models.BooleanField(default=False)
class Meta:
db_table='party'
ordering=['name',]
def __unicode__(self):
return self.name
class Person(models.Model):
party = models.OneToOneField(Party, editable=False)
firstName=models.CharField(max_length=60)
lastName=models.CharField(max_length=60)
...
def save(self):
if None == self.party :
print 'Creating party for person'
p = Party()
p.partyType = 'P'
p.save()
self.party = p
# Get address to set party name used in list
city=""
state=""
postalCode=""
try:
partyAddress = PartyPostalAddress.objects.get(party=self.party)
address = partyAddress.postalAddress
city=address.city
state=address.state
postalCode=address.postalCode
except PartyPostalAddress.DoesNotExist:
pass
self.party.name = '%s, %s - %s, %s %s' %(self.lastName, self.firstName, city, state, postalCode)
self.party.save()
super(Person,self).save()
My assumption was to write a def delete() in my model like this:
def delete(self):
self.party.delete()
self.delete()
And an admin action like so:
class PersonAdmin(admin.ModelAdmin):
list_display = ('lastName','firstName')
search_fields = ('firstName', 'lastName')
actions=['really_delete_selected']
def get_actions(self, request):
actions = super(PersonAdmin, self).get_actions(request)
del actions['delete_selected']
return actions
def really_delete_selected(self, request, queryset):
for obj in queryset:
obj.delete()
if queryset.count() == 1:
message_bit = "1 person was"
else:
message_bit = "%s people were" % queryset.count()
self.message_user(request, "%s successfully deleted." % message_bit)
really_delete_selected.short_description = "Delete selected entries"
That deletes person.party and most of person, but throws an error because person's party OneToOneField is now empty. The specific error is:
"AssertionError at /admin/common/person/
Party object can't be deleted because its id attribute is set to None."
Any ideas? This, this, and this question are related, but only one of them utilizes the OneToOneField and he did that erroneously.
I am getting a feeling that it should be as simple as switching the sequence of deleting the two (unless you have tried this already). Since the person is associated with party, once you delete person, you cannot access party. Hence you should do
person.party.delete()
person.delete()
Got it cleaned up and working!
My model:
class Party(models.Model):
name = models.CharField(max_length=100)
...
class Person(models.Model):
party = models.OneToOneField(Party, editable=False)
firstName=models.CharField(max_length=60)
lastName=models.CharField(max_length=60)
def delete(self):
d = self.party.id
Party.objects.get(id__exact=d).delete()
My admin:
class PersonAdmin(admin.ModelAdmin):
actions=['really_delete_selected']
def get_actions(self, request):
actions = super(PersonAdmin, self).get_actions(request)
del actions['delete_selected']
return actions
def really_delete_selected(self, request, queryset):
for obj in queryset:
obj.delete()
if queryset.count() == 1:
message_bit = "1 person was"
else:
message_bit = "%s people were" % queryset.count()
self.message_user(request, "%s successfully deleted." % message_bit)
really_delete_selected.short_description = "Delete selected entries"
...