I am trying to give roles based on the ID of the role to users in a guild once they join however, cannot seem to get it to give when I provide the role ID and I can when I provide the role name.
I've tried both
#Nao.event
async def on_member_join(member):
database = mysql.connector.connect(
host='localhost',
user='root',
passwd='',
database='Nao'
)
cursor = database.cursor()
query = "SELECT role FROM autorole WHERE server = %s"
values = (member.guild.id,)
cursor.execute(query, values)
result = cursor.fetchall()
for role in result:
role = discord.utils.get(member.guild.roles, name='Members')
await member.add_roles(role)
Which works and
#Nao.event
async def on_member_join(member):
database = mysql.connector.connect(
host='localhost',
user='root',
passwd='',
database='Nao'
)
cursor = database.cursor()
query = "SELECT role FROM autorole WHERE server = %s"
values = (member.guild.id,)
cursor.execute(query, values)
result = cursor.fetchall()
for role in result:
role = discord.utils.get(member.guild.roles, id=role[0])
await member.add_roles(role)
which does not work and gives me the error;
await req(guild_id, user_id, role.id, reason=reason) AttributeError: 'NoneType' object has no attribute 'id'
Related
#client.command(pass_context=True)
async def meme(ctx):
embed = discord.Embed(title="", description="")
async with aiohttp.ClientSession() as cs:
async with cs.get('https://www.reddit.com/r/dankmemes/new.json?sort=hot') as r:
res = await r.json()
embed.set_image(url=res['data']['children'] [random.randint(0, 25)]['data']['url'])
await ctx.send(embed=embed)
so that is my meme command rn i need help to put the title and amount of upvotes in the embed
You can set those attributes via
embed.title = "<your-title>"
embed.url = "https://<your-url>"
And for the upvotes you could add a field
embed.add_field(name = "Upvotes", value = "<your upvotes>")
I was creating a createrole command and I wanted to show some info about the role, such as the name, color, and id, but how did I get the role id? I tried looking on this site, Reddit, and the API reference but I couldn't find an answer.
This is what I have now:
#bot.command(name='createrole')
async def createrole(ctx, *, content):
guild = ctx.guild
await guild.create_role(name=content)
role = get(ctx.guild.roles, name='content')
roleid = role.id
description = f'''
**Name:** <#{roleid}>
**Created by:** {ctx.author.mention}
'''
embed = discord.Embed(name='New role created', description=description)
await ctx.send(content=None, embed=embed)
Quick Fix:
Right now you are passing the string 'content' to your get function instead of the variable with the name content. Try replacing the following line:
role = get(ctx.guild.roles, name='content')
with this:
role = get(ctx.guild.roles, name=content)
Much more efficient and less error prone way of doing it:
await guild.create_role returns the role object created, meaning you don't need to refetch it by name and can just do this:
#bot.command(name='createrole')
async def createrole(ctx, *, content):
guild = ctx.guild
role = await guild.create_role(name=content)
roleid = role.id
description = f'''
**Name:** <#{roleid}>
**Created by:** {ctx.author.mention}
'''
embed = discord.Embed(name='New role created', description=description)
await ctx.send(content=None, embed=embed)
In my app, i have a chained dropdown in which i am getting the second dropdown via jquery ajax, which works well.So i am trying to edit this saved data and load it back to an edit form, but the dropdown is showing empty. This is what i have done so far
Here is my model.py
class SchoolFees(models.Model):
fid = models.ForeignKey(FacultyData, on_delete= models.SET_NULL, null=True)
did = models.ForeignKey(DepartmentData, on_delete= models.SET_NULL, null=True)
sid = models.ForeignKey(SessionData, on_delete= models.SET_NULL, null=True)
amount = models.CharField(max_length=30)
def __str__(self):
return self.amount
forms.py
class FeesCreationForm(forms.ModelForm):
fid = forms.ModelChoiceField(queryset=FacultyData.objects.all(), empty_label="--Select Faculty--",
widget=forms.Select(attrs={'class': 'form-control'}))
did = forms.ModelChoiceField(queryset=DepartmentData.objects.all(), empty_label="--Select Faculty First--",
widget=forms.Select(attrs={'class': 'form-control'}))
sid = forms.ModelChoiceField(queryset=SessionData.objects.all(), empty_label="--Select Session--",
widget=forms.Select(attrs={'class': 'form-control'}))
class Meta:
model = models.SchoolFees
fields = ['sid', 'fid', 'did', 'amount']
widgets = {
'amount': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter Amount'})
}
def __init__(self, *args, **kwargs):
super(FeesCreationForm, self).__init__(*args, **kwargs)
self.fields['did'].queryset = DepartmentData.objects.none()
# Get did queryset for the selected fid
if 'fid' in self.data:
try:
fd = int(self.data.get('fid'))
self.fields['did'].queryset = DepartmentData.objects.filter(fid_id=fd).order_by('id')
except (ValueError, TypeError):
pass # invalid input from the client; ignore and use empty queryset
Here is my view.py
def edit_fee(request, pk):
app = settings.CONFIG
post = get_object_or_404(SchoolFees, pk=pk)
if request.method == 'POST':
form = FeesCreationForm(request.POST, instance=post)
if form.is_valid():
form.save()
messages.add_message(request, messages.WARNING, "Fees record updated successfully")
return redirect('bursary:create_fee')
else:
# bring edit form out
form = FeesCreationForm(instance=post)
table = FeesTable(SchoolFees.objects.all())
RequestConfig(request, paginate={'per_page': 10}).configure(table)
context = {"form": form, "fees": table, 'app': app}
return render(request, 'editfee.html', context)
I expect that the saved value is pass to the dropdown with other form fields which are already showing
After going through this post, i was able to solve it when reading the comments. All i needed was to add a backward relationship to my init function.
class FeesCreationForm(forms.ModelForm):
fid = forms.ModelChoiceField(queryset=FacultyData.objects.all(), empty_label="--Select Faculty--",
widget=forms.Select(attrs={'class': 'form-control'}))
did = forms.ModelChoiceField(queryset=DepartmentData.objects.all(), empty_label="--Select Faculty First--",
widget=forms.Select(attrs={'class': 'form-control'}))
sid = forms.ModelChoiceField(queryset=SessionData.objects.all(), empty_label="--Select Session--",
widget=forms.Select(attrs={'class': 'form-control'}))
class Meta:
model = models.SchoolFees
fields = ['sid', 'fid', 'did', 'amount']
widgets = {
'amount': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Enter Amount'})
}
def __init__(self, *args, **kwargs):
super(FeesCreationForm, self).__init__(*args, **kwargs)
self.fields['did'].queryset = DepartmentData.objects.none()
# Get did queryset for the selected fid
if 'fid' in self.data:
try:
fd = int(self.data.get('fid'))
self.fields['did'].queryset = DepartmentData.objects.filter(fid_id=fd).order_by('id')
except (ValueError, TypeError):
pass # invalid input from the client; ignore and use empty queryset
elif self.instance.pk:
self.fields['did'].queryset = self.instance.fid.departmentdata_set.order_by('id')
#backward relation - for this faculty selected, check its deparm
#every department has its faculty
# #in other word, which dept has their foreign key pointing to the current instance of faculty
I am using python-social-auth and django-rest-framework to allow users signup with their social accounts in my app.
my case is similar to this post
Users are not created after login with facebook (probably an homonymy case)
I use django-rest-framework's TokenAuthentication to authenticate users
When using my custom user model, when an authtoken is available in the header (user is logged in) the social user account created is linked to the user whose Token is attached to the request as expected, but when there is no token available, it fails to create a new account.
But when using the default django user model, everything works as expected. I suspect that I am not configuring my custom user model properly.
Below is my settings file can you please look and see if you can find out what I am doing wrong.
Thanks in advance.
My settings file
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
),
'PAGINATE_BY': 10
}
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.request',
'social.apps.django_app.context_processors.backends',
)
SOCIAL_AUTH_FACEBOOK_KEY = os.environ.get('FB_APP_ID')
SOCIAL_AUTH_FACEBOOK_SECRET = os.environ.get('FB_APP_SECRET')
SOCIAL_AUTH_FACEBOOK_EXTENDED_PERMISSIONS = ['email']
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_USER_MODEL = 'users.FLUser'
SOCIAL_AUTH_TWITTER_KEY = os.environ.get('TWITTER_APP_ID')
SOCIAL_AUTH_TWITTER_SECRET = os.environ.get('TWITTER_APP_SECRET')
AUTHENTICATION_BACKENDS = (
'social.backends.twitter.TwitterOAuth',
'social.backends.facebook.FacebookOAuth2',
'social.backends.facebook.Facebook2OAuth2',
'django.contrib.auth.backends.ModelBackend',
)
SOCIAL_AUTH_PIPELINE = (
'social.pipeline.social_auth.social_details',
'social.pipeline.social_auth.social_uid',
'social.pipeline.social_auth.auth_allowed',
'social.pipeline.social_auth.social_user',
'social.pipeline.user.get_username',
'social.pipeline.social_auth.associate_by_email',
'social.pipeline.user.create_user',
'social.pipeline.social_auth.associate_user',
'social.pipeline.social_auth.load_extra_data',
'social.pipeline.user.user_details'
# 'apps.users.pipeline.user_details',
)
Custom Manager
class FLUserManager(BaseUserManager):
def _create_user(self, username, email, password,
is_staff, is_superuser, **extra_fields):
"""
Creates and saves a User with the given username, email and password.
"""
now = timezone.now()
if not email:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
user = self.model(username=username, email=email,
is_staff=is_staff, is_active=True,
is_superuser=is_superuser, last_login=now,
date_joined=now, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, email=None, password=None, **extra_fields):
return self._create_user(username, email, password, False, False,
**extra_fields)
def create_superuser(self, username, email, password, **extra_fields):
return self._create_user(username, email, password, True, True,
**extra_fields)
Custom User Model
class FLUser(AbstractBaseUser, PermissionsMixin):
GENDER = (
('M', 'Male'),
('F', 'Female'),
)
email = models.EmailField(
verbose_name=_('email address'),
max_length=255,
unique=True,
)
username = models.CharField(
verbose_name=_('username'),
max_length=30,
unique=False,
help_text=_('Required. 30 characters or fewer. Letters, numbers and '
'#/./+/-/_ characters'),
validators=[
validators.RegexValidator(re.compile('^[\w.#+-]+$'),
_('Enter a valid username.'), 'invalid')
]
)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
birthday = models.DateTimeField(
blank=True,
default=None,
null=True
)
gender = models.CharField(
max_length=1,
choices=GENDER,
default=None,
null=True
)
avatar = models.ImageField(
upload_to='media/avatars',
blank=True,
default=None,
null=True
)
sm_avatar = models.URLField(
blank=True,
default=None,
null=True,
verbose_name=_('Social Media Avatar')
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_('Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.')
)
is_admin = models.BooleanField(default=False)
objects = FLUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'username',]
def is_authenticated(self):
return True
def get_full_name(self):
return '''{} {}'''.format(self.first_name, self.last_name)
def get_short_name(self):
return self.first_name
#property
def is_staff(self):
return self.is_admin
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
# On Python 3: def __str__(self):
def __unicode__(self):
return self.email
def email_user(self, subject, message, from_email=None):
"""
Sends an email to this User.
"""
send_mail(subject, message, from_email, [self.email])
class Meta:
ordering = ('id', 'first_name',)
verbose_name = _('user')
verbose_name_plural = _('users')
#receiver(post_save, sender=FLUser)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
The View
#api_view(['POST'])
#permission_classes((AllowAny,))
#strategy()
def register_by_access_token(request, backend):
backend = request.strategy.backend
if backend.name == 'twitter':
token = {
'oauth_token': request.DATA.get('access_token'),
'oauth_token_secret': os.environ.get('TWITTER_APP_OAUTH_SECRET'),
}
elif backend.name == 'facebook':
token = request.POST.get('access_token')
else:
raise Response('Wrong backend type', status=HTTP_400_BAD_REQUEST)
user = backend.do_auth(
access_token=token,
user=request.user.is_authenticated() and request.user or None
)
if user and user.is_active:
login(request, user)
user = UserAuthSerializer(user)
return Response(user.data, status=HTTP_200_OK)
else:
return Response({'detail': 'Unable to authenticate user'}, status=HTTP_400_BAD_REQUEST)
not sure if this matters at all, but i think your inheritance is a little wrong for your custom user model (mixins come before):
class FLUser(PermissionsMixin, AbstractBaseUser):
....
var users = from u in db.UserProfiles select new UsersViewModel{
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled,
Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
};
I would like to select the roles from the database and create a list of UsersViewModel. However Entity Framework is trying to execute the projection on the SQL side, where there is no equivalent to Roles.GetRolesForUser.
What would be an alternative to this or how am I suppose to execute any method inside the query?
The easiest is to get the data you want from SQL, then after the query executes, iterate through the results and populate the additional details from the function in your code.
Example:
var users = (from u in db.UserProfiles select new UsersViewModel{
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled
}).ToList();
foreach(var user in users){
user.Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault();
}
The key to remember here is to separate out what you're doing (understanding the separation of concerns in your architecture). Take care of the SQL first, then augment the data from other sources, in your case the Role Provider.
You can force the query to execute before creating the ViewModels by adding ToList():
var users = from u in db.UserProfiles.ToList()
select new UsersViewModel{
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled,
Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
};
As CodeMonkey1313 noted, I strongly suggest you apply some sort of filter in your query:
var users = from u in db.UserProfiles
.Where( x => /* apply filter here */ )
.ToList() //Force query to execute
select new UsersViewModel {
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled,
Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
};
You can convert your Queryable to an Enumerable that executes locally:
var users = (from u in db.UserProfiles select new UsersViewModel{
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled)}
).AsEnumerable()
.Select(u => new {
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled,
Role = Roles.GetRolesForUser(u.UserName) })
.FirstOrDefault()