Can someone pls explain how can I filter users posts if user is subscriber or not?
'QuerySet' object has no attribute 'subs'
I use custom user
class Every(AbstractBaseUser):
user = models.OneToOneField(settings.AUTH_USER_MODEL, unique=True)
name = models.CharField(max_length=30, blank=True)
Here is post model:
class Post(models.Model):
user = models.ForeignKey(User, blank=True, null=True)
text = models.TextField(max_length=1200)
A subscriber model:
class Sub(models.Model):
user = models.OneToOneField(User, related_name='user')
subs = models.ManyToManyField(User, blank=True, related_name='subs')
A view that I'm trying to use:
def tape(request, every_id):
context = {}
context.update(csrf(request))
post_form = PostForm
pform = post_form
sub = Sub.objects.filter(subs=every_id)# here I get users that intersting for my user
tape = Post.objects.filter(user=sub.subs).order_by("-timestamp")
username = request.user
context = {"username": username, "pform": pform, "tape": tape, "sub": sub,}
return render(request, 'tape.html', context)
actually it would be better to use a class view. But here is an answer with an usual view. We need to get subscription's and subscribers's ids before we start filter posts
here is even a bit more :-)
def get_user_id_list(user):
"""Returns a list of subscribers's ids"""
try:
sub = user.user
Sub.DoesNotExist:
return []
return sub.subs.all().values_list('user_id', flat=True)
def get_user_id_list_2(user):
"""Returns a list of subscription's ids"""
return user.subs.values_list('user_id', flat=True)
def tape(request):
pform = PostForm
user_id_list = get_user_id_list_2(request.user)
logger.info('user_id_list = {}'.format(user_id_list))
tape = Post.objects.filter(user_id__in=user_id_list).order_by("-timestamp")
username = request.user
context = {
"username": username,
"pform": pform,
"tape": tape,
"sub": sub,
}
return render(request, 'tape.html', context)
Related
I'm creating a registration page which contains 3 input fields: name, email, password. In my User model class, I've created a user_role method:
from models.base_model import BaseModel
from flask_login import UserMixin
import peewee as pw
class Users(BaseModel, UserMixin):
name = pw.CharField(max_length=100, unique=True)
email = pw.CharField(max_length=100, unique=True)
password = pw.CharField()
role = pw.CharField(max_length=50)
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
def __repr__(self):
return f"User: {self.name}, {self.email}, {self.role}"
def user_roles(self):
user_email = self.email
self.roles = ["user","admin"]
check_email = ["test#testing.com"]
if user_email == check_email:
return self.roles == "admin"
else:
return self.roles == "user"
The check_email is use to check if the email that a user fill in the field is equal to the check_email value. If it does, the role should be assign as 'admin'. In my route file, this is what it look like when saving to the database:
if form.validate_on_submit():
name = form.name.data
email = form.email.data
raw_password = form.password.data
password = generate_password_hash(raw_password, method="sha256", salt_length=20)
role = Users.user_roles(email)
new_user = Users(name=name, email=email, password=password, role=role)
Now when I tried to test out the registration form, this is the error it gave me:
I want to know is there a way to fix this error?
PS: I'm doing this for testing purposes to see if I could assign user role. I would probably add more user roles in the future, so I don't think Flask-Admin could help me
You have your user_roles method defined as a class method when it can and should probably be a static method. Also you are calling user_roles with the email string but the try to access self.email in the method. Just change that and you are good to go.
def get_role(email):
check_email = "test#testing.com"
if email == check_email:
return "admin"
else:
return "user"
Edit: Forgot to remove brackets as we don't want an array but just the string.
class PhoneBook:
def __init__(self):
self.contacts = {}
def __str__(self):
return str(self.contacts)
def add(self, name, mobile=None, office=None, email=None):
self.contacts["Name"] = name
self.contacts["Mobile"] = mobile
self.contacts["Office"] = office
self.contacts["Email"] = email
obj = PhoneBook()
obj.add("Kim", office="1234567", email="kim#company.com")
obj.add("Park", office="2345678", email="park#company.com")
print(obj)
I tried to make PhoneBook class to add up the dictionary lists as I put .add method to the class variable but every time the class variable calls the PhoneBook() class, the dictionary initialization occurs and only the last data remains in the dictionary(I suppose :S)
Is there any way to solve this problem? Thank you.
The issue is, you're using the same dictionary key "Name" to store your contacts. Instead, put real name as a key to dictionary and this key will hold another dictionary. For example:
import pprint
class PhoneBook:
def __init__(self):
self.contacts = {}
def __str__(self):
return pprint.pformat(self.contacts, width=30)
def add(self, name, mobile=None, office=None, email=None):
self.contacts[name] = {
"Mobile": mobile,
"Office": office,
"Email": email,
}
obj = PhoneBook()
obj.add("Kim", office="1234567", email="kim#company.com")
obj.add("Park", office="2345678", email="park#company.com")
print(obj)
Prints:
{'Kim': {'Email': 'kim#company.com',
'Mobile': None,
'Office': '1234567'},
'Park': {'Email': 'park#company.com',
'Mobile': None,
'Office': '2345678'}}
I have a custom user model that have a preferred_language field. I want all the emails (activation and password reset) to be sent translated to the language that user specified in profile.
class CustomUser(AbstractBaseUser, PermissionsMixin):
...
LANGUAGE_CHOICES = (
(1, "English"),
(2, "Русский")
)
preferred_language = models.PositiveSmallIntegerField(choices=LANGUAGE_CHOICES, default=2,
verbose_name=_("Preferred language"))
I thought about setting custom email class but didn't saw in navive djoser's classes any points where I could explicitly set the language of outcome emails despite of ready-to-be-translated style of email templates:
class ActivationEmail(BaseEmailMessage):
template_name = 'email/activation.html'
def get_context_data(self):
context = super(ActivationEmail, self).get_context_data()
user = context.get('user')
context['uid'] = utils.encode_uid(user.pk)
context['token'] = default_token_generator.make_token(user)
context['url'] = settings.ACTIVATION_URL.format(**context)
return context
Reset password view (which's refference is settings.EMAIL.activation used in ActivationEmail class above):
class ResetPassword(ActionViewMixin, generics.GenericAPIView):
...
def send_password_reset_email(self, user):
context = {'user': user}
to = [get_user_email(user)]
settings.EMAIL.password_reset(self.request, context).send(to)
def send_activation_email(self, user):
context = {'user': user}
to = [get_user_email(user)]
settings.EMAIL.activation(self.request, context).send(to)
In your case I would use the override context manager that stores the current language on enter (in order to sent the email) and restores it on exit.
from django.utils import translation
def send_password_reset_email(self, user):
context = {'user': user}
to = [get_user_email(user)]
lang_code = user.lang_code # retrieve user's language code here
with translation.override(lang_code):
settings.EMAIL.password_reset(self.request, context).send(to)
def send_activation_email(self, user):
context = {'user': user}
to = [get_user_email(user)]
lang_code = user.lang_code # retrieve user's language code here
with translation.override(lang_code):
settings.EMAIL.activation(self.request, context).send(to)
I have customized a module that include a many2one field. Now, I would like to set the default value for that field with the codition is: [[u'bom_ids', u'!=', False]]. i have tried below code but it did not work probebly
width_id = field.Many2one('sale.order.line.width', default ='_get_width_default')
def _get_width_default(self, cr, uid, context=None):
res = self.pool.get('product.template').search(cr, uid, [(u'bom_ids', u'!=', False)], context=context)
return res and res[0] or False
default = {
'width_id' : _get_width_default,
}
Could you guy please help me to point what is the problem and how to sovle the problem and finnally get my purpose. Thank for watching
import logging
_logger = logging.getLogger(__name__)
def _get_width_default(self, cr, uid, context=None):
#REPLACE DOMAIN WITH SOMETHING RELEVANT
domain = []
res = self.pool.get('sale.order.line.width').search(cr, uid, domain, context=context)
_logger.info("PREPARING DEFAULT VALUE")
_logger.info(res)
return res[0] or False
width_id = fields.many2one('sale.order.line.width')
_defaults = {
'width_id' : _get_width_default,
}
What do you see as far as logging is concerned? Try the above code (v7 style).
Odoo9 Style (NEW API)
import logging
_logger = logging.getLogger(__name__)
def _get_width_default(self):
#REPLACE DOMAIN WITH SOMETHING RELEVANT
domain = []
res = self.env['sale.order.line.width'].search(domain)
_logger.info("PREPARING DEFAULT VALUE")
_logger.info(res)
return res[0].id or False
width_id = fields.many2one('sale.order.line.width',default=_get_width_default)
I'm using Mongoengine.
When I do a:
>>> Grant.objects().first().client_id
The result is as expected.
ObjectId('526fd0da82353536892f22ae')
But, when I search based on the client_id,
>>> Grant.objects(client_id="526fd0da82353536892f22ae").first()
I get a InvalidQueryError:
InvalidQueryError: Cannot resolve field "client_id"
Here's what my Grant model looks like:
class Grant(db.Document):
#user_id = db.StringField()
user = db.ReferenceField(User)
client_id = db.StringField()
client = db.ReferenceField(Client)
code = db.StringField()
redirect_uri = db.StringField()
expires = db.DateTimeField()
scopes = db.ListField()
#for soft-deleting the grant
is_deleted = db.BooleanField(default=False)
#property
def user_id(self):
return self.user.id
#property
def client_id(self):
return self.client.id
def delete(self):
self.is_deleted = True
Can someone go through this code and point out the problem?
Do you try to use it like :
Grant.objects(client_id=ObjectId("526fd0da82353536892f22ae")).first()