No module named 'blog.slugs' - django

I am trying to create a blog website.but when i try to import generate_unique_slug from .slugs django throws an error
No module named 'blog.slugs'. can you help me fix this?
models.py
from django.db import models
from user_profile.models import User
from django.utils.text import slugify
from ckeditor.fields import RichTextField
from .slugs import generate_unique_slug
# Create your models here.
class Category(models.Model):
title = models.CharField(max_length=150, unique=True)
slug = models.SlugField(null=True, blank=True)
created_date = models.DateField(auto_now_add=True)
def __str__(self) -> str:
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save(*args, **kwargs)
class Blog(models.Model):
user = models.ForeignKey(
User,
related_name='user_blogs',
on_delete=models.CASCADE
)
category = models.ForeignKey(
Category,
related_name='category_blogs',
on_delete=models.CASCADE
)
title = models.CharField(
max_length=250
)
slug = models.SlugField(null=True, blank=True)
banner = models.ImageField(upload_to='blog_banners')
description = RichTextField()
created_date = models.DateField(auto_now_add=True)
def __str__(self) -> str:
return self.title
def save(self, *args, **kwargs):
updating = self.pk is not None
if updating:
self.slug = generate_unique_slug(self, self.title, update=True)
super().save(*args, **kwargs)
else:
self.slug = generate_unique_slug(self, self.title)
super().save(*args, **kwargs)
admin.py
from django.contrib import admin
from .models import *
# Register your models here.
admin.site.register(Category)
admin.site.register(Blog)
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
'user_profile',
'ckeditor',
]
when i delete this code from .slugs import generate_unique_slug the error disappears.maybe I'm importing it wrong?I will be very grateful if you help to solve the problem

In this line
from .slugs import generate_unique_slug
You are trying to import generate_unique_slug from you project file, and as you commented you don’t have this file in your project
The solution is you should write this function generate_unique_slug you can put it in file call slugs.py and it will work, or write this function inside model and delete this line
Note: this function should contain the logic for generate a unique slug depends on what you want

Related

Restrict multiple login for a user in Django Rest Framework

I am attempting to restrict multiple login from a single user in my webapp and for the same I am following this tutorial:
https://dev.to/fleepgeek/prevent-multiple-sessions-for-a-user-in-your-django-application-13oo
I followed this step by step and when I am logging in using postman(or anything):
http://localhost:8000/api/token/
I am unable to see any session that has been created in the ORM. Is it because I am using JWTAuthentication ?
apps.py
class AccountsConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
signals.py
#receiver(user_logged_in)
def on_user_logged_in(sender, request, **kwargs):
LoggedInUser.objects.get_or_create(user=kwargs.get('user'))
#receiver(user_logged_out)
def on_user_logged_out(sender, **kwargs):
LoggedInUser.objects.filter(user=kwargs.get('user')).delete()
Models.py
class User(AbstractUser):
is_company = models.BooleanField(default=False)
is_employee = models.BooleanField(default=False)
is_client = models.BooleanField(default=False)
#property
def full_name(self):
return self.first_name + " " + self.last_name
class LoggedInUser(models.Model):
user = models.OneToOneField(User, related_name='logged_in_user', on_delete=models.CASCADE)
# Session keys are 32 characters long
session_key = models.CharField(max_length=32, null=True, blank=True)
def __str__(self):
return self.user.username
When I try runserver with this configuration it shows the following error:
django.core.exceptions.ImproperlyConfigured: Application labels aren't
unique, duplicates: users
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'corsheaders',
'users',
'users.apps.AccountsConfig',
Where users is the application name

using get_context_data() method to retrieve a list of dependant objects within DetailView Django

I am creating a simple car dealership application in Django 3 whereby when goes to a detail page of a category it should list all cars that belong in that category , so in my case car objects are dependent objects of their respective category . I have tried to implement this using get_context_data() method and referencing the two respective models within the DetailView here is my code
models.py category
from django.db import models
from django.urls import reverse
# Create your models here.
class Category(models.Model):
name = models.CharField(null=False, blank=False, max_length=20)
description = models.TextField(null=False, blank=False, max_length=120)
image = models.ImageField(upload_to='images/')
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('category_detail', args=[str(self.id)])
models.py cars
from django.db import models
from django.urls import reverse
from categories.models import Category
# Create your models here.
class Car(models.Model):
image = models.ImageField(upload_to='images/cars/')
make = models.CharField(null=False, blank=False, max_length=30)
model = models.CharField(null=False, blank=False, max_length=30)
year = models.IntegerField(null=False, blank=False)
transmission = models.CharField(null=False, blank=False, max_length=30)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.model
def get_absolute_url(self):
return reverse('car_detail', args=[str(self.id)])
views categories
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from .models import Category
from cars.models import Car
# Create your views here.
class CategoryList(ListView):
model = Category
template_name = 'category_list.html'
class CategoryDetailView(DetailView):
model = Category
template_name = 'category_detail.html'
def get_context_data(self, *args, **kwargs):
context = super(CategoryDetailView, self).get_context_data(
*args, **kwargs)
context['category_cars'] = Car.objects.filter(
category=self.request.name)
return context
urls categories
from django.urls import path
from .views import CategoryList, CategoryDetailView
urlpatterns = [
path('categories/', CategoryList.as_view(), name='categories'),
path('categories/<int:pk>/', CategoryDetailView.as_view(), name='category_detail')
]
so using my above implementation results into an error
any suggestions so as to achieve my desired functionality?
Parameters are transferred through kwargs also your parameter name is pk and not name
def get_context_data(self, *args, **kwargs):
context = super(CategoryDetailView, self).get_context_data(
*args, **kwargs)
context['category_cars'] = Car.objects.filter(
category=context['object']
)
return context
But you actually don't need to do this as Category objects have access to their related Car objects ( car_set):
{% for car in object.car_set.all %}
{{car.make}}
{% endfor %}

AUTH_USER_MODEL refers to model 'base.User' that has not been installed for custom auth backend

I'm trying to customize auth backend while customized auth model but keep facing this error because i'm using get_user_model() function.
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'base.User' that has not been installed
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'base.apps.BaseConfig',
'core.apps.AccountsConfig',
'system.apps.SystemConfig',
]
custom Backend:
class UserBackend(object):
def authenticate(self, request, username=None, password=None, **kwargs):
usermodel = User
try:
usr = usermodel.objects.get(username=username)
password_valid = usr.check_password(password)
if usr and password_valid:
return usr
raise PermissionDenied
except usermodel.DoesNotExist:
return PermissionDenied
return None
def get_user(self, user_id):
usermodel = User
try:
return usermodel.objects.get(pk=user_id)
except usermodel.DoesNotExist:
return None
Edit:
settings:
AUTH_USER_MODEL = 'base.User'
AUTHENTICATION_BACKENDS = (
'base.models.UserBackend',
)
base.User model:
class User(AbstractUser):
fullname = models.CharField(max_length=35, null=True, blank=True)
picture = models.ManyToManyField('ImageFile', verbose_name="ProfilePicture", blank=True)
bio = models.CharField(max_length=255, null=True, blank=True)
link = models.URLField(null=True, blank=True, default="")
is_private = models.BooleanField(default=False)
is_official = models.BooleanField(default=False)
Note: UserBackend is on the end of file and class User(AbstractUser) is above it
There was an import in base.models file, from django.contrib.auth.backends import ModelBackend which caused this error even when i removed custom AUTHENTICATION_BACKENDS.after i removed this import, everything works fine although i moved backend class from base.models to backend file in the base app (i think its not necessary, i just did it for more readable codes)
For me it was the same. It took me over an hour to find out that you cannot have the CustomBackend(BaseBackend) and the CustomUser(AbstractUser) in the models.py of your app. This info is nowhere to be found in the official Django docs.
Django Version: 3.1.2
Python Version: 3.8.2
models.py of the app "Users":
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
last_name = models.CharField(max_length=50)
first_name = models.CharField(max_length=50)
auth.py (arbitrary name, living in the "Users" app):
from django.db import models
from django.contrib.auth.backends import BaseBackend
class UserAuth(BaseBackend):
def authenticate(self, request, username, password):
pass
def get_user(self, user_id):
pass
settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users.apps.UsersConfig'
]
AUTH_USER_MODEL = 'users.User'
AUTHENTICATION_BACKENDS = [
'users.auth.UserAuth'
]

Django Tastypie: maximum recursion depth exceeded

I am following the tutorial from django-tastypie, after Hooking Up The Resource(s), I went to http://localhost:8000/api/entry/?format=json, I got this error in JSON:
{"error_message": "maximum recursion depth exceeded", "traceback": "Traceback (most recent call last):\n\n File \"C:\\Python27\\lib\\site-packages\\django_tastypie-0.9.14-py2.7.egg\\tastypie\\resources.py\", line 202, in wrapper\n response = callback(request, *args, **kwargs)\n\n\
models.py:
from tastypie.utils.timezone import now
from django.contrib.auth.models import User
from django.db import models
from django.template.defaultfilters import slugify
class Entry(models.Model):
user = models.ForeignKey(User)
pub_date = models.DateTimeField(default=now)
title = models.CharField(max_length=200)
slug = models.SlugField()
body = models.TextField()
def __unicode__(self):
return self.title
def save(self, *args, **kwargs):
# For automatic slug generation.
if not self.slug:
self.slug = slugify(self.title)[:50]
return super(Entry, self).save(*args, **kwargs)
api.py:
from tastypie.resources import ModelResource
from myapp.models import Entry
class EntryResource(ModelResource):
class Meta:
queryset = Entry.objects.all()
resource_name = 'entry'
try uncomment "(r'^blog/', include('myapp.urls')" which you put under urlpatterns and then run your application again.
Just comment out the "(r'^blog/', include('myapp.urls')" which can be found under urlpatterns in your urls.py and then rerun your application.

Django admin choice field

I have a model that has a CharField and in the admin I want to add choices to the widget. The reason for this is I'm using a proxy model and there are a bunch of models that share this CharField but they each have different choices.
class MyModel(MyBaseModel):
stuff = models.CharField('Stuff', max_length=255, default=None)
class Meta:
proxy = True
class MyModelAdmin(admin.ModelAdmin):
fields = ('stuff',)
list_display = ('stuff',)
admin.site.register(MyModel, MyModelAdmin)
For this model I want to use MY_CHOICES in MyModelAdmin.
Do I override a widget? Do I need to override the whole form?
from django.contrib import admin
from django import forms
class MyModel(MyBaseModel):
stuff = models.CharField('Stuff', max_length=255, default=None)
class Meta:
proxy = True
class MyModelForm(forms.ModelForm):
MY_CHOICES = (
('A', 'Choice A'),
('B', 'Choice B'),
)
stuff = forms.ChoiceField(choices=MY_CHOICES)
class MyModelAdmin(admin.ModelAdmin):
fields = ('stuff',)
list_display = ('stuff',)
form = MyModelForm
admin.site.register(MyModel, MyModelAdmin)
See: https://docs.djangoproject.com/en/dev/ref/forms/fields/#choicefield
You don't need a custom form.
This is the minimum you need:
# models.py
from __future__ import unicode_literals
from django.db import models
class Photo(models.Model):
CHOICES = (
('hero', 'Hero'),
('story', 'Our Story'),
)
name = models.CharField(max_length=250, null=False, choices=CHOICES)
# admin.py
from django.contrib import admin
from .models import Photo
class PhotoAdmin(admin.ModelAdmin):
list_display = ('name',)
admin.site.register(Photo, PhotoAdmin)
You can override formfield_for_choice_field() that way you don't need to create a new form.
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_choice_field(self, db_field, request, **kwargs):
if db_field.name == 'status':
kwargs['choices'] = (
('accepted', 'Accepted'),
('denied', 'Denied'),
)
if request.user.is_superuser:
kwargs['choices'] += (('ready', 'Ready for deployment'),)
return super().formfield_for_choice_field(db_field, request, **kwargs)
See formfield_for_choice_field
You need to override the form the ModelAdmin is going to use:
class MyForm(forms.ModelForm):
stuff = forms.CharField('Stuff', max_length=255, choices=MY_CHOICES, default=None)
class Meta:
model = MyModel
fields = ('stuff', 'other_field', 'another_field')
class MyModelAdmin(admin.ModelAdmin):
fields = ('stuff',)
list_display = ('stuff',)
form = MyForm
If you need your choices to be dynamic, maybe you could do something similar to:
class MyForm(forms.ModelForm):
stuff = forms.CharField('Stuff', max_length=255, choices=MY_CHOICES, default=None)
def __init__(self, stuff_choices=(), *args, **kwargs):
# receive a tupple/list for custom choices
super(MyForm, self).__init__(*args, **kwargs)
self.fields['stuff'].choices = stuff_choices
and in your ModelAdmin's __init__ define what MY_CHOICES is going to be and assign the form instance there instead:
Good luck! :)
in Gerard's answer, if you keep :
def __init__(self, stuff_choices=(), *args, **kwargs):
then when you will try to add new model from admin, you will always get 'This field is required.' for all required fields.
you should remove stuff_choices=() from initialization:
def __init__(self,*args, **kwargs):
You need to think of how you are going to store the data at a database level.
I suggest doing this:
Run this pip command: pip install django-multiselectfield
In your models.py file:
from multiselectfield import MultiSelectField
MY_CHOICES = (('item_key1', 'Item title 1.1'),
('item_key2', 'Item title 1.2'),
('item_key3', 'Item title 1.3'),
('item_key4', 'Item title 1.4'),
('item_key5', 'Item title 1.5'))
class MyModel(models.Model):
my_field = MultiSelectField(choices=MY_CHOICES)
In your settings.py:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
#.....................#
'multiselectfield',
)
Watch the MAGIC happen!
Source:
https://pypi.python.org/pypi/django-multiselectfield
Below a solution that works immediately with Postgres' special ArrayField:
# models.py
class MyModel(models.Model):
class Meta:
app_label = 'appname'
name = models.CharField(max_length=1000, blank=True)
ROLE_1 = 'r1'
ROLE_2 = 'r2'
ROLE_3 = 'r3'
ROLE_CHOICES = (
(ROLE_1, 'role 1 name'),
(ROLE_2, 'role 2 name'),
(ROLE_3, 'role 3 name'),
)
roles = ArrayField(
models.CharField(choices=ROLE_CHOICES, max_length=2, blank=True),
default=list
)
# admin.py
class MyModelForm(ModelForm):
roles = MultipleChoiceField(choices=MyModel.ROLE_CHOICES, widget=CheckboxSelectMultiple)
#admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm
list_display = ("pk", "name", "roles")
(Django 2.2)