I'm implementing a soft delete for class Animal. Following the example in the docs I created a custom manager for it, but the query field, 'Inactive_Date' is undefined. I tried putting the AnimalManager class def inside the Animal class def; no help.
Code from models.py:
class AnimalManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(Inactive_Date == None)
class Animal(models.Model):
Name = models.CharField(max_length=64, unique=True)
Inactive_Date = models.DateField(null=True, blank=True)
Animal_Type = models.ForeignKey(Animal_Type, null=True, on_delete=models.SET_NULL, default=None)
Comments = models.CharField(max_length=255, blank=True)
def __str__(self) -> str:
return (self.Name)
def delete(self):
self.Inactive_Date = datetime.datetime.today()
self.save()
objects = AnimalManager() # omits inactive animals
Seems like you have double equal sign on the filtering
return super().get_queryset().filter(Inactive_Date == None)
^^
But regardless, checking for NULL value can be done via __isnull
return super().get_queryset().filter(Inactive_Date__isnull=True)
Related
Order_by not working in FloatField type Django
models.py
class CourseCategory(models.Model):
category = models.CharField(max_length=100, unique=True, null=False)
description = models.TextField(blank=True)
class Meta(object):
app_label = "course_category"
def __unicode__(self):
return self.category
Coursetrack Model
class CourseTrack(models.Model):
category = models.ForeignKey(CourseCategory)
course_id = CourseKeyField(max_length=255, db_index=True)
tracks = models.FloatField(null=True, blank=True, default=None)
active = models.BooleanField(default=True)
class Meta(object):
app_label = "course_category"
def __unicode__(self):
return str(self.course_id)
TopCoursesCategory
class TopCoursesCategory(models.Model):
category = models.ForeignKey(CourseCategory)
class Meta(object):
app_label = "course_category"
def __unicode__(self):
return str(self.category)
I added here order_by(), as you can see but its not working.
view.py
def get_popular_courses_ids():
popular_category_id = CourseCategory.objects.filter(category='Popular')
popular_courses_ids = CourseTrack.objects.values('course_id').filter(category=popular_category_id).order_by('tracks')
course_id_list = []
for course_id in popular_courses_ids:
course_id_list.append(course_id['course_id'])
return course_id_list
I think the query you have posted is wrong.
You have used the following lines.
popular_category_id = CourseCategory.objects.filter(category='Popular')
popular_courses_ids = CourseTrack.objects.values('course_id').filter(category=popular_category_id).order_by('tracks')
In the first line, you have used filter and you have used the resulting variable as category= in your second query which you cannot do. For category= in your second query to work, you would need to give a single element and not a queryset. Replace your filter with get in the first query and it might work fine.
Or
If you think that popular_category_id can have more than one row for the category popular, leave the first query as it is and change your second query to
popular_courses_ids = CourseTrack.objects.values('course_id').filter(category__in=popular_category_id).order_by('tracks')
I have changed category to category__in.
Hello I would like to implement method for player to take list of players (query set) and leave clan
I'm looking for something like:
Player.leave_clan([1,2,3])
Player.leave_clan([p1,p2,p3])
What I have tried is the method which takes list of account_ids [1,2,3] and then I use updated method on query, but here I have to pass only account IDs
def remove_leavers(self, leavers, clan):
players = Player.objects.filter(account_id__in=leavers)
players.update(clan=None,
previous_clan=clan)
and with my current models I could call something like:
leavers = Player.objects.filter(account_id__in=[1,2,3]
for player in leavers:
player.leave_clan()
But I do not think it's right way to do. I use following models down bellow, thank you for all suggestion and recommendations.
I think I need custom manager but I did not know how to write it even after reading the documentation.
from django.db import models
class Clan(models.Model):
clan_id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100)
tag = models.CharField(max_length=5)
def __str__(self):
return "{tag}".format(tag=self.tag)
#property
def members(self):
return Player.objects.filter(clan=self)
def kick_player(self, player):
player.leave_clan()
class Player(models.Model):
account_id = models.IntegerField(primary_key=True)
account_name = models.CharField(max_length=250)
clan = models.ForeignKey('Clan',
on_delete=models.CASCADE,
blank=True,
null=True,
related_name='current_clan')
previous_clan = models.ForeignKey('Clan',
on_delete=models.CASCADE,
blank=True,
null=True,
related_name='previous_clan')
def __str__(self):
return '{0} - {1}'.format(self.account_name, self.account_id)
def leave_clan(self):
self.previous_clan = self.clan
self.clan = None
self.save()
If you want to use a Manager you can do this :
class PlayerManager(models.Manager):
def leave_clan(self, players):
"""
Take a list of player. And removed them from their clan
"""
for player in players:
player.leave_clan()
class Player(models.Model):
account_id = models.IntegerField(primary_key=True)
account_name = models.CharField(max_length=250)
clan = models.ForeignKey('Clan',
on_delete=models.CASCADE,
blank=True,
null=True,
related_name='current_clan')
previous_clan = models.ForeignKey('Clan',
on_delete=models.CASCADE,
blank=True,
null=True,
related_name='previous_clan')
def __str__(self):
return '{0} - {1}'.format(self.account_name, self.account_id)
def leave_clan(self):
self.previous_clan = self.clan
self.clan = None
self.save()
How to use it
Player.objects.leave_clan(LIST_PLAYERS)
Hope it helps you.
Models:
class Owner(models.Model):
name = models.CharField(max_length=255)
def __unicode__(self):
return self.name
class SomeThing(models.Model):
own_id = models.IntegerField(unique=True)
description = models.CharField(max_length=255, blank=True)
owner = models.ForeignKey(Owner, blank=True, null=True)
def __unicode__(self):
return self.description
Serializers:
class OwnerNameField(serializers.RelatedField):
def to_internal_value(self, data):
pass
def to_representation(self, value):
return value.name
def get_queryset(self):
queryset = self.queryset
if isinstance(queryset, (QuerySet, Manager)):
queryset = queryset.all()
lista = [Owner(name="------------")]
lista.extend(queryset)
return lista
class OwnerSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Owner
fields = ('name', 'id')
class ThingSerializer(serializers.ModelSerializer):
owner = OwnerNameField(queryset=Owner.objects.all())
class Meta:
model = SomeThing
fields = ('own_id', 'description', 'owner')
Basically it works as intended. But when i add some fields to Owner class i would like to see all these fields in output of ThingSerializer (and be able to parse them - string doesn't suit here). I could change field owner to owner = OwnerSerializer() which gives me what i need. But when i want to add SomeThing object (tested in API browser) i also need add new Owner object - and i don't want it, i want use existing Owner object. How can i achieve it?
Finally i got it. This question describes exactly my problem and provided answers work as a charm!
I have a bunch of message records that I would like to assign to different taskboxes.
#models.py
class TaskBox(models.Model):
name = models.CharField(max_length=64, blank=False)
def __str__(self):
return u'%s' % (self.name)
class Admin:
pass
class InboxEntry(models.Model):
job_number = models.CharField(max_length=14, unique=False, blank=False, null=False)
job_name = models.CharField(max_length=64, unique=False, blank=False, null=False)
request = models.CharField(max_length=64, choices=PRINT_CHOICES, blank=True, null=True)
date_due = models.DateTimeField(("Due"),auto_now=False)
note = models.TextField(max_length=1000, unique=False, blank=True, null=True)
assigned_by = models.ForeignKey(UserProfile, blank=False, null=False)
box = models.ForeignKey(TaskBox)
assigned_to = models.ManyToManyField(UserProfile, related_name='name', blank=True)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default="Awaiting Action")
def __str__(self):
return u'%s %s' % (self.job_number, self.job_name)
class Admin:
pass
class Meta:
ordering = ['status']
The idea is for the template to have some generic tags like {{ for taskbox in taskboxes }} to create a separate div for each taskbox that will hold a table for that box's records. My problem is constructing the view function...
#views.py
def display_prdInboxEntry(request, id):
if request.method == 'POST':
form = PrdInboxForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('taskmanager/display/'+ id +'/')
else:
form = PrdInboxForm(request.POST)
return HttpResponseRedirect('taskmanager/display/'+ id +'/')
else:
form = PrdInboxForm()
user = request.user
**taskboxes = TaskBox.objects.all()
records_1 = InboxEntry.objects.filter(taskboxes[id]=1)
records_2 = InboxEntry.objects.filter(taskboxes[id]=2)
records_3 = InboxEntry.objects.filter(taskboxes[id]=3)
..... **
return render_to_response('taskmanager/taskmanager_view.html', {'form': form, 'taskboxes': taskboxes, 'records_1' : records_1, 'records_2' : records_2, 'records_3' : records_3, 'user': user}, context_instance=RequestContext(request))
The InboxEntry model has a field called "box" that's just a reference to the TaskBox model. I need a way to map say... TaskBox id 1 with all of the InboxEntry objects with "box = 1" so that I can populate the templates appropriately. Can I construct the function to accommodate this, or am I going about it the wrong way entirely?
It sounds like you're looking for the automatically-generated attribute for reverse lookups. You can get a QuerySet of all InboxEntries associated with a TaskBox like this:
TaskBox.objects.filter(id=1).inboxentry_set.all()
See the documentation on related objects.
I have a model with ManyToManyField to another model. I would like to get all the info on a particular record (including the related info from other models) return by JSON.
How to get django-piston to display those values? I would be happy with just primary keys.
Or can you suggest another option ?
I may be wrong, but this should do it:
class PersonHandler(BaseHandler):
model = Person
fields = ('id', ('friends', ('id', 'name')), 'name')
def read(self, request):
return Person.objects.filter(...)
You need to define a classmethod on the handler that returns the many-to-many data, I don't believe Piston does this automatically.
class MyHandler(BaseHandler):
model = MyModel
fields = ('myfield', 'mymanytomanyfield')
#classmethod
def mymanytomanyfield(cls, myinstance):
return myinstance.mymanytomanyfield.all()
My code:
Models:
class Tag(models.Model):
"""docstring for Tags"""
tag_name = models.CharField(max_length=20, blank=True)
create_time = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.tag_name
class Author(models.Model):
"""docstring for Author"""
name = models.CharField(max_length=30)
email = models.EmailField(blank=True)
website = models.URLField(blank=True)
def __unicode__(self):
return u'%s' % (self.name)
class Blog(models.Model):
"""docstring for Blogs"""
caption = models.CharField(max_length=50)
author = models.ForeignKey(Author)
tags = models.ManyToManyField(Tag, blank=True)
content = models.TextField()
publish_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __unicode__(self):
return u'%s %s %s' % (self.caption, self.author, self.publish_time)
Handle:
class BlogAndTagsHandler(BaseHandler):
allowed_methods = ('GET',)
model = Blog
fields = ('id' 'caption', 'author',('tags',('id', 'tag_name')), 'content', 'publish_time', 'update_time')
def read(self, request, _id=None):
"""
Returns a single post if `blogpost_id` is given,
otherwise a subset.
"""
base = Blog.objects
if _id:
return base.get(id=_id)
else:
return base.all() # Or base.filter(...)
Works petty good.