Django ManyToMany relationship having through parameter [duplicate] - django

I have a many-to-many relationship with a through table like so:
class Chapter(models.Model):
name = models.CharField(max_length=255,)
slides = models.ManyToManyField('Slide', blank=True, related_name='chapters', through='SlideOrder')
# ...
class Slide(models.Model):
title = models.CharField(max_length=255,)
# ...
class SlideOrder(models.Model):
chapter = models.ForeignKey(Chapter)
slide = models.ForeignKey(Slide)
number = models.PositiveIntegerField()
I am able to get the slides for a chapter in order like so:
chapter = Chapter.objects.get(pk=1)
chapter_slides = chapter.slides.order_by('slideorder')
However, when working on an individual slide instance I am unable to access the slide order:
slide = Slide.objects.get(pk=1)
If I do the following on my slide instance I can see all possible fields:
print slide._meta.get_all_field_names()
['title', u'chapters', 'slideorder', u'id']
However trying to access the slideorder field gives me the following:
slide.slideorder
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Slide' object has no attribute 'slideorder'
I am able to access all attributes listed except slideorder. How can I access a slide's order?

You can either filter on the SlideOrder model directly
slide = Slide.objects.get(pk=1)
slide_orders = SlideOrder.objects.filter(slide=slide)
for slide_order in slide_orders:
print slide_order.number
or follow the foreign key backwards:
slide = Slide.objects.get(pk=1)
slide_orders = slide.slideorder_set.all()
for slide_order in slide_orders:
print slide_order.number
See the docs on extra fields on many-to-many relationships for more info.

You can use slide.slideorder_set as documented in the django docs

Related

Get Data from Choice field in Django rest framework

I have searched and tried out all solutions provided for this question in similar problem but they're not working for me. I am getting the following error when trying to get data from an endpoint
Got AttributeError when attempting to get a value for field
hotel_type on serializer HotelDetailSerializer. The serializer
field might be named incorrectly and not match any attribute or key on
the Hotels instance. Original exception text was: 'Hotels' object
has no attribute 'get_hotel_Type_display'.
This is my model field truncated for clarity
class Hotels(models.Model):
HOTEL_TYPE = (
('hotel', "Hotel"),
('apartment', "Apartment"),
('villa', "Villa"),
hotel_Type = models.CharField(
max_length=20,
choices=HOTEL_TYPE,
default='hotel', null=True, blank=True
#property
def hotel_type(self):
return self.get_hotel_Type_display()
This is my serializer class also truncated for clarity
class HotelDetailSerializer(serializers.ModelSerializer):
hotel_type = serializers.Field(source='hotel_type.hotel_Type')
class Meta:
model = Hotels
fields = ("hotel_type" )
This is the apiview
class HotelDetailAPIView(RetrieveAPIView):
"""Display details of a single hotel"""
queryset = Hotels.objects.all()
serializer_class = HotelDetailSerializer
permission_classes = ()
lookup_field = 'slug'
Could anyone kindly assist me figure out why this is not working? Thanks
EDIT
I am editing this question to add more context. I have been doing some debugging in Django shell. This is what i am getting
>>> from hotels.models import Hotels
>>> h = Hotels.objects.all()
>>> for n in h:
... print (n.hotel_Type)
...
(<django.db.models.fields.CharField>,)
>>> for n in h:
... print (n.get_hotel_Type_display())
...
Traceback (most recent call last):
File "<console>", line 2, in <module>
AttributeError: 'Hotels' object has no attribute 'get_hotel_Type_display'
I am following Django's get_FOO_display() tutorial and i still cannot get this work. I am not seeing anything wrong with my Hotels model. Could this be a bug in Django? Kindly assist
This really has eaten me up. I finally found the issue was a misplaced comma on my model field as shown below
class Hotels(models.Model):
HOTEL_TYPE = (
('hotel', "Hotel"),
('apartment', "Apartment"),
('villa', "Villa"),
hotel_Type = models.CharField(
max_length=20,
choices=HOTEL_TYPE,
default='hotel', null=True, blank=True
),# <--------------This comma was the source of my problems
#property
def hotel_type(self):
return self.get_hotel_Type_display()

Not getting fields and their values which are ManyToManyField type

I have a django model named Persona:
class Persona(models.model):
name=models.CharField(max_length=100,primary_key=True)
pages_visited = models.ManyToManyField(Page)
items_searched = models.ManyToManyField(ItemsSearched)
visits = models.IntegerField(null=True,blank=True)
connect = models.CharField(max_length=True,null=True,blank=True)
image = models.ForeignKey('Image',on_delete=models.CASCADE)
def __str__(self):
return self.name
I have an object for this model:
<QuerySet [<Persona: aman>]>
Now when i am trying to get the values of all fields for this object i can see all fields and their corresponding values except fields which are ManyToManyField type.
I get the following result when i execute this : Persona.objects.filter(name='aman').values()
<QuerySet [{'visits': None, 'image_id': 3, 'name': 'aman', 'connect': 'call'}]>
I cannot see 'items_searched' and 'pages_visited' fields and their corresponding values though when i log into admin i can see them.
These are the images which show you my execution:
Command Prompt
Admin Panel
To access m2m filed in django there is .all() keyword refer this
p1 = Persona.objects.filter(name='aman')
p1_m2m = p1.pages_visited.all()
which will give the result you wanted
I believe what you're looking for is Inlines.
In your admin file, add
from .models import Page # Edit this import according to your project structure
class PagesVisitedInline(admin.TabularInline):
model = Page
class PersonaAdmin(admin.ModelAdmin):
[...] # admin code goes here
inlines = [PagesVisitedInline, ]
You could use StackedInline aswell if you prefer, read more here.

I do not understand this error involving two objects with a many-to-many relation with one another

I am implementing a web interface for email lists. When a list administrator logs in, the site will visually display which lists they are an owner of and corresponding information about the lists. For this I have decided to have two tables:
1) An owner table which contains entries for information about list administrators. Each of these entries contains a 'ManyToManyField' which holds the information about which lists the owner in any given entry is an administrator for.
2) A list table which contains entries with information about each email list. Each entry contains the name of the list a 'ManyToManyField' holding information about which owners are administrators the list.
Here is the code in models.py:
from django.db import models
class ListEntry(models.Model):
name = models.CharField(max_length=64)
owners = models.ManyToManyField('OwnerEntry')
date = models.DateTimeField('date created')
class Meta:
ordering = ('name',)
class OwnerEntry(models.Model):
name = models.CharField(max_length=32)
lists = models.ManyToManyField('ListEntry')
class Meta:
ordering = ('name',)
I have already set up a simple local database to create a basic working website with. I have populated it with test entries using this code:
from list_app.models import *
from datetime import *
le1 = ListEntry(
name = "Physics 211 email list",
date = datetime.now(),
)
le1.save()
le2 = ListEntry(
name = "Physics 265 email list",
date = datetime(2014,1,1),
)
le2.save()
oe1 = OwnerEntry(
name = 'wasingej',
)
oe1.save()
oe1.lists.add(le1,le2)
le1.owners.add(oe1)
le2.owners.add(oe1)
oe2 = OwnerEntry(
name = 'doej',
)
oe2.save()
oe2.lists.add(le1)
le1.owners.add(oe2)
Here is where my error occurs: When the user has logged in via CAS, I have them redirected to this page in views.py:
def login_success(request):
u = OwnerEntry(name=request.user)
print(u.name)
print(u.lists)
return HttpResponse("login success!")
At the line 'print(u.lists)', I get the error "" needs to have a value for field "ownerentry" before this many-to-many relationship can be used.
What am I doing wrong here?
Your model structure is broken, for a start. You don't need ManyToManyFields on both sides of the relationship, only one - Django will provide the accessor for the reverse relationship.
Your issue is happening because you are not querying an existing instance from the database, you are instantiating an unsaved one. To query, you use model.objects.get():
u = OwnerEntry.objects.get(name=request.user.username)
You need to provide the actual class to the ManyToManyField constructor, not a string.
https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/

Django Tastypie POST request for OneToOne relation

I have recently started django-tastypie and so far loving the framework. With said that, I am getting below issue on POST for OneToOne relation to model and spent good amount of time but couldn't figured whats missing. Here is the Model and Resource code -
Model
class Question(TimeStampedModel):
question_title = models.CharField("question title", max_length=100)
question_desc = models.TextField("question description", max_length=1000)
.......
Second model is having OneToOne relation with Question -
class QuestionAnswer(TimeStampedModel):
question = models.OneToOneField(Question)
.....
Resource
QuestionAnswerResource -
class QuestionAnswerResource(ModelResource):
question = fields.ForeignKey('myapp.api.QuestionResource', 'question')
class Meta:
queryset = QuestionAnswer.objects.all()
resource_name='questionanswer'
QuestionResource -
class QuestionResource(ModelResource):
questionanswer = fields.OneToOneField('myapp.api.QuestionAnswerResource', 'questionanswer', full=True)
class Meta:
queryset = Question.objects.all()
resource_name = 'question'
With the above setup, I get correct response on GET with Question instance along with its answer attribute. However when I try to POST data to save question/answer on this one it fails with below error -
"{"error_message": "", "traceback": "Traceback (most recent call
last):\n\n File
\"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 192,
...................................................................................... line 636, in hydrate\n
value = super(ToOneField, self).hydrate(bundle)\n\n File
\"/Library/Python/2.7/site-packages/tastypie/fields.py\", line 154, in
hydrate\n elif self.attribute and getattr(bundle.obj,
self.attribute, None):\n\n File
\"/Library/Python/2.7/site-packages/Django-1.4.1-py2.7.egg/django/db/models/fields/related.py\", line 343, in get\n raise
self.field.rel.to.DoesNotExist\n\nDoesNotExist\n"}"
Can someone point out what I am missing?
I think that this:
questionanswer = fields.OneToOneField('myapp.api.QuestionAnswerResource', 'questionanswer', full=True)
causes problem. There is no questionanswer field in your Question model and Django expects that.
To test, you may want to see whether you can create instances in the shell. Tastypie docs say the following about the ToOneField:
This subclass requires Django’s ORM layer to work properly.
and I think this might not be the case here.
To provide answers for a question you may want to set related_name, like so:
question = fields.ForeignKey('myapp.api.QuestionResource', 'question', related_name = 'questionanswer')

Django get method is yielding an error

I'm following a Django book (Django 1.0 Web Site Development). I'm finding that the book, although straight forward and easy to read, leaves out small details. However, this error that I'm getting, I have not been able to find a solution online. Thanks for any help.
Below, I added the Tag class to my models.py file.
from django.db import models
from django.contrib.auth.models import User
class Link(models.Model):
url = models.URLField(unique=True)
class Bookmark(models.Model):
title = models.CharField(max_length=200)
user = models.ForeignKey(User)
link = models.ForeignKey(Link)
class Tag(models.Model):
name = models.CharField(max_length=64, unique=True)
bookmarks = models.ManyToManyField(Bookmark)
Then I attempt to run the following code at the python shell:
from bookmarks.models.import *
bookmark = Bookmark.objects.get(id=1)
As a result, I get the following error:
Traceback (most recent call last):
File "(console)", line 1, in (module)
File "c:\Python27\lib\site\-packages\django\db\models\manager.py", line 132, in get
return self.get_query_set().get(*args, **kwargs)
File "c:\Python27\lib\site-packages\django\db\models\query.py", line 349, in get
% self.model._meta.object_name)
DoesNotExist: Bookmark matching query does not exist.
The error means just what it says. DoesNotExist is raised by QuerySet.get() if there is no object in the database that would match the conditions given to the QuerySet. In this case it means there is no Bookmark object in the database with an ID equal to 1.
Did you add any data in the Bookmark table yet? DoesNotExist is raised by get if there is no record corresponding to your query. i.e. if there is no record corresponding to id=1.