Foreign key to user model not working as expected - python

I have a django project with a custom user model.
I have this Subscriptions model that uses the custom user model as its foreign key.
class Subscriptions(models.Model):
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
app_subscriptions = models.CharField(max_length=100)
def __str__(self):
return self.app_subscriptions
But if I try to retreive all users app_subscriptions with ..app_subscriptions_set.all() it always returns with the following error:
AttributeError: 'CustomUser' object has no attribute 'app_subscriptions_set'
I have the same type of model in use here:
from django.db import models
class Software(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Version(models.Model):
version = models.CharField(max_length=50)
software = models.ForeignKey(Software, on_delete=models.CASCADE)
def __str__(self):
return self.version
And on this model I have no issues querying for all software versions with ...version_set.last().
Anyone have any ideas? Thank you in advance.

Try using user_instance.subscriptions_set.all() instead of .app_subscriptions_set.all().
The default accesor is the model name, all lowercase, and appends _set. See the docs about it, or this question.
Your model Version is just like that:
software_instance.version_set.all()

Related

Django cant figure out how to use foreign key

class Project_types(models.Model):
project_type = models.CharField(max_length=200)
def __str__(self):
return self.project_type
class Projects(models.Model):
project_types = models.ForeignKey(Project_types, on_delete=models.CASCADE)
project = models.CharField(max_length=200)
def __str__(self):
return self.project
When I try to run Project_types(project_type='games').item_set.all()
I get an error saying that there is no attribute item set.
class Project_types(models.Model):
project_type = models.CharField(max_length=200)
def __str__(self):
return self.project_type
class Projects(models.Model):
project_types = models.ForeignKey(Project_types, on_delete=models.CASCADE)
project = models.CharField(max_length=200)
def __str__(self):
return self.project
First there's a few problems with your model.
First model names shouldn't be pluralized
Here a Projects (should be Project) has one project_type, and a Project_types (should be ProjectType) has one project.
To run the query you want:
Project_types.filter(project_type='games').item_set.all()
the correct query would be:
Project_types.filter(project_type='games').projects_set.all()
use projects instead of items,
the related manager is based on the Model name (in this case Projects becomes projects_set)
see here https://docs.djangoproject.com/en/3.2/topics/db/examples/many_to_one/
The .item_set attribute does not exist on the instance you have created by running:
Project_types(project_type='games')
It seems to me that you are trying to get all Projects of the type 'games'.
To do that, you'll have to use the QuerySet of the Projects class like this:
Projects.objects.filter(project_types__project_type='games').all()
Additionally, a suggestion: try to name all your model classes using singular CamelCase, so that they will be easier to understand. In your example, Project_types should be ProjectType, while Projects should be Project.
Project_types(project_type='games') doesn't actually return any object. That's why you got that attribute error. You need to add a filter or use get. Something like below:
Project_types.objects.get(project_type='games').item_set.all()
Or
Project_types.objects.filter(project_type='games').item_set.all()

'AttributeError' when overriding 'RelatedField' in Serializing

I'm working with a Django project that implement the Rest framework.
I have this model
class Portfolio(models.Model):
ticker = models.CharField(max_length=10, default='???')
name = models.CharField(max_length=25)
amount = models.FloatField()
owner = models.ForeignKey('auth.User', related_name='portfolio', on_delete=models.CASCADE)
def __str__(self):
return self.name
Note on the 'owner' ForeignKey.
And in my serializers.py I have this
class MyRelatedField(serializers.RelatedField):
def to_representation(self, obj):
return 'Test'
class UserSerializer(serializers.ModelSerializer):
portfolio = serializers.MyRelatedField(many=True)
class Meta:
model = User
fields = ('url', 'id', 'username', 'portfolio')
AS I read on the docs, I should override the RelatedField (which I did) if I want a custom representation. However when I try to run I get this error
AttributeError: module 'rest_framework.serializers' has no attribute 'MyRelatedField'
No matter what I return in MyRelatedField, the same error occurs.
My question is how to debug and ideally, fix this error.
Thank you.
Since MyRelatedField and UserSerializer located in same module you need to replace portfolio = serializers.MyRelatedField(many=True) with portfolio = MyRelatedField(many=True).

Creating many to many relation with AUTH_USER_MODEL in django via intermediary model

I am trying to create the following models. There is a ManyToMany relation from Entry to AUTH_USER_MODEL via the EntryLike intermediate model.
class BaseType(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
creation_time = models.DateTimeField(auto_now_add=True)
last_update_time = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Title(BaseType):
text = models.CharField(max_length=100)
description = models.TextField()
class EntryLike(BaseType):
entry = models.ForeignKey(Entry)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
class Entry(BaseType):
title = models.ForeignKey(Title, on_delete=models.PROTECT)
text = models.TextField()
user = models.ForeignKey(settings.AUTH_USER_MODEL)
liked_by_users = models.ManyToManyField(settings.AUTH_USER_MODEL, through='EntryLike', through_fields=('entry', 'user'))
Running migrations on the above model scheme throws the error: AttributeError:'str' object has no attribute 'meta'.
Any help in resolving this error would be highly appreciated. Am new to Django & Python, but not to Web Development.
The issue is that settings.AUTH_USER_MODEL is almost certainly not a model instance. It's probably a string that constrains the choices another model can make - settings would be a strange place to leave a model definition.
To do a MTM between the user model and your field above you need need to do:
from django.contrib.auth.models import User
class Entry(BaseType):
title = models.ForeignKey(Title, on_delete=models.PROTECT)
text = models.TextField()
user = models.ForeignKey(User)
def __str__(self):
return self.title
I've added the str function so that it gives a more sensible return when you're manipulating it in admin/shell.
I'd also question whether you need the second set of fields (removed here), as you can use select related between the Entry and EntryLike join table, without any duplication of the fields - you can probably go that way, it's just a bit unnecessary.
Lastly, I'd note that the way I'm using it above just uses the default User object that comes with Django - you may wish to customise it. or extend the base class as you've done here with your own models' base class.
(All of this is predicated on AUTH_USER_MODEL not being a model instance - if it is, can you post the model definition from settings.py? )

Django - Get Object with ForeignKey

versions:
Python 3.4
Django 1.7
I created a gallery app with different galleries and their own images.
my models:
from django.db import models
class Gallery(models.Model):
title = models.CharField(max_length=200)
pub_date = models.DateTimeField('publish date')
def __str__(self):
return self.title
class Image(models.Model):
title = models.CharField(max_length=200)
gallery = models.ForeignKey(Gallery)
pub_date = models.DateTimeField('publish date')
file = models.ImageField(upload_to='img/gallery/'+str(Gallery.objects.get(pk=str(gallery)).id)+'/')
def __str__(self):
return self.title
you see my Gallery and Image model. While creating an Image in the Backend it should create a folder dynamicly in "img/gallery/gallery_id"
my problem is that Image.gallery is a ForeignKey here and I cant convert it into a int or string to use it. Is there a function to get the ID from my Gallery object with the ForeignKey from my Image object?
my solution
Gallery.objects.get(pk=str(gallery)).id
is not working.
btw: I thought foreignkey is always an int like id? isnt it?
The way Django works, a convenient method is automatically added that will give you the model instance that the foreign key represents. This is your gallery field. There is another field, called the same but with _id appended, that holds the actual foreign key value.
As petkostas said, you can pass a function that accepts the instance and filename arguments. You should use gallery_id instead of gallery.id to prevent an unnecessary call to the database.
def gallery_folder(instance, filename):
return '/'.join(['img/gallery', instance.gallery_id, filename])
class Image(models.Model):
...
file = models.ImageField(upload_to=gallery_folder)
upload to can be a callback:
https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.FileField.upload_to
so:
def gallery_folder(instance, filename):
return '/'.join(['img/gallery', instance.gallery.id, filename])
class Image(models.Model):
title = models.CharField(max_length=200)
gallery = models.ForeignKey(Gallery, related_name='images')
pub_date = models.DateTimeField('publish date')
file = models.ImageField(upload_to=gallery_folder)
def __str__(self):
return self.title
Also add related_name, makes reverse queries easier, also you can opt for instance.gallery.title if you want.

Update intermediate model object using generic view in django

How can i update the existing object of intermediate model using generic view?
class Person(models.Model):
name = models.CharField(max_length=128)
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
Currently i'm using generic views concept to update object, but I'm facing problem hoe to update field which exist in intermediate model?
If i generate modelform for Group class, then how can i update the associated field (intermediate model field) using generic view concept?
In above i want to update invite reason field
Thanks in advance
I think there are some missing views in generic or class-based views (which I highly recommend you if your are not already using them), and other people thinks in the same way...
Take a look at django-extra-views project, it implements those missing views.

Categories

Resources