Django contrib auth users manytomany - django

Hello I want to make several users to one post with manytomany relationship.
from django.contrib.auth.models import User
class Post(models.Model):
author = models.ManyToManyField(User)
title = models.CharField(max_length=150)
slug = models.SlugField(max_length=255, unique=True)
body = models.TextField()
But I got this error
Post needs to have a value for field "id" before this many-to-many relationship can be used.
Can anyone tell me what the problem is?

In order to setup a many-to-many relationship the ID of the post is mandatory. Check in your database if the post(s) has an ID. The error message says its empty, so add it manually in the database (not recommended) or rerun the post its migrations and make sure the ID is auto-incremented.

Related

Filter django query set based on whether a foreign key relationship exists

So I have two models.
class Post(models.Model):
id = models.OidField('object id', unique=True)
class ArchivedFlag(models.Model):
post = models.ForeignKey(post,
on_delete=models.CASCADE,
related_name='archived_flag')
user = models.ForeignKey(User,
on_delete=models.CASCADE,
related_name='archives')
In views.py I have generated a list of all posts by some criteria, 'plist'.
I want to filter the list based on posts that DO NOT have an ArchivedFlag object relationship. Basically the ArchivedFlag model is a tool hide certain posts.
How can I do this? I'm trying to do something along the lines of
plist = plist.exclude(models.ForeignKey.Post exists)
but I'm unsure of the exact syntax.
You can exclude Post objects for which anArchivedFlag exists with:
Post.objects.exclude(archived_flag__isnull=False)
or easier with a simple filter:
Post.objects.filter(archived_flag=None)
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

How can I link model in new app with specific model data in allauth?

In Django, I have installed allauth. Then I have created a new app, where user's actions will be. I want to link each of the actions with allauth's user data within EmailAddress model.
My questions are:
Normally, data is defined by user_action = models.CharField(max_length=200) and such. ForeignKey on user action does not allow defining field types, at least from what I've seen. How can I define it, or is it okay not to define it?
How can I define the relationship with data in allauth's model that's not anywhere near this new app? For example, I have:
from django.db import models
import allauth.account.models
class Button(models.Model):
button_one = models.ForeignKey('EmailAddress', on_delete=models.CASCADE)
def __str__(self):
return self.button_one
It does not work. The error shows:
input.Button.comment: (fields.E300) Field defines a relation with model 'EmailAddress', which is either not installed, or is abstract.
input.Button.comment: (fields.E307) The field input.Button.comment was declared with a lazy reference to 'input.emailaddress', but app 'input' doesn't provide model 'emailaddress'.
The allauth model data ("user") in question is:
class EmailAddress(models.Model):
user = models.ForeignKey(allauth_app_settings.USER_MODEL,
verbose_name=_('user'),
on_delete=models.CASCADE)
email = models.EmailField(unique=app_settings.UNIQUE_EMAIL,
max_length=app_settings.EMAIL_MAX_LENGTH,
verbose_name=_('e-mail address'))
verified = models.BooleanField(verbose_name=_('verified'), default=False)
primary = models.BooleanField(verbose_name=_('primary'), default=False)
objects = EmailAddressManager()
I'm using virtualenv and have allauth installed within the project.
So EmailAddress is your User model?
In that case you might be able to do this via the standard way by referring to settings.py
Import . from settings
class Button(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)

Django models: database design for user and follower

In Django model I am making a table 'followers', which has:
user's id. (this is followed by)
user's id (this is follower)
that's simple a user can follow other users.
How should I define the model in Django?
I tried this, but does not work:
user = models.ForeignKey('self')
follower_id = models.ForeignKey('self')
How should this be done?
thanks
The 'self' argument won't work unless you have a model called self.
Assuming that your assignment model is called Following, and you're using the built in User model then you can do:
class Following(models.Model):
target = models.ForeignKey('User', related_name='followers')
follower = models.ForeignKey('User', related_name='targets')
This will likely need some further uniqueness and validation logic.
Note the related_name attribute, see https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.related_name. This means that for a given user object you can do user.targets.all() to get users they follow, and user.followers.all() to get users who follow them.
Note also that Django returns target model instances, not IDs, in the ORM. This means that even though the underlying table may be called follower_id, in the python code following.follower will return an actual User object.
Seeing as Following is actually the through table for the many-to-many relationship between Users. I would create a Profile model which extends the Django User model, and then declare the many-to-many relationship (using ManyToManyField).
from django.contrib.auth.models import User
from django.db import models
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
following = models.ManyToManyField(User, related_name='followers')
Use the many to many field.
followers = models.ManyToManyField('self', symmetrical=False)

Django UserProfile slug field

I'm looking to create a url to visit a user profile using a slug. Ie. I want to visit /profile/myname to bring up my user profile. What I am having difficulties with is implementing the slug field for a user model.
Additionally, not sure if this matters or not but I have created a UserProfile model which extends the standard User model as shown below:
from django.contrib.auth.models import User
from autoslug import AutoSlugField
class UserProfile(models.Model):
user = models.ForeignKey(User, related_name='profile_name')
about_me = models.TextField(null=True, blank=True)
slug = AutoSlugField(populate_from='User.username', default='', unique=True)
which gives the error (when trying to migrate):
DETAIL: Key (slug)=() is duplicated.
I believe the urls to be correct but have included it for reference (in an app named profile):
url(r'^(?P<slug>[\w-]+)', views.detail, name='detail')
It means you already have some records in userprofile table with empty/null values in slug field. Because you've marked that field as unique=True it can only have one field with empty value. To avoid this error, delete the records with empty value in slug field, or just assign them a unique slug and you'll be good to go.
And as you can understand from above, having default='' in a field that has unique=True wont work. Unique means unique, even '' as an empty value is considered a unique value and can be used in just one row if you have unique=True. That also means you cannot have any default value in a unique field.

Best Practice for following multiple authentication backends in Django?

I am trying to implement an authentication system for 2 different sets of users in Django. A student(using his username & password), A developer (using his email & password). Currently I have a (common) UserProfile model which will be shared by Student, Developer. Here is my models code:
class UserProfile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(max_length=50, null=True, blank=True)
slug = models.SlugField(max_length=50, db_index=True, unique=True)#this will be used as his unique url identifier
objects = UserProfileManager()
class Meta:
abstract = True
class Student(UserProfile):
''' some student specific fields might go here '''
class Developer(UserProfile):
''' some developer specific fields might go here '''
And in settings.py I gave:
AUTH_PROFILE_MODULE = 'users.UserProfile'
I was getting authentication working with just UserProfile model. But as soon as I introduced Student, Developer the whole thing screwed up. I am getting
UserProfile has no attribute
'DoesNotExist'
(this is from the UserProfileManager exists method) and also
SiteProfileNotAvailable
error. (I am getting these errors even before I started writing email auth backend.). Am I missing anything ? What's the best path to follow to achieve what I wanted.
The problem might be the abstract definition of UserProfile. Things should work when you leave the 'abstract = True' away. But be aware of how this changes your table scheme.