I wanted to implement an anonymous cart system to my django site. I saw on internet that I can achieve with the following javascript code:
我想在我的Django站点上实现一个匿名购物车系统。我在网上看到,我可以用下面的Java代码来实现:
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
let device = getCookie('device')
if (device == null || device == undefined){
device = uuidv4()
}
document.cookie ='device=' + device + ";domain=;path=/"
Which is embedded at the end of 'base.html' which is a template every other html uses. like this: <script src="{% static 'js/cookies.js'%}"></script>
它嵌入在‘base.html’的末尾,这是其他所有html都使用的模板。如下所示:<脚本src=“{%静态‘js/cookies.js’%}”>
Followed by this home page code:
后跟此主页代码:
class HomeView(ListView):
template_name = "index.html"
def get(self, *args, **kwargs):
context = get_base_lists(self.request)
...
return render(self.request, self.template_name, context)
...
def get_base_lists(request):
...
cart, created = Order.objects.get_or_create(
user=auth_status(request),
device=auth_status(request, False)
)
# Order is created in such a way that user or device can be null, but not at the same time.
...
return {'cart': cart }
...
def auth_status(request, for_user: bool = True):
if request.user.is_authenticated:
return None if for_user is False else request.user
else:
device_name = request.COOKIES['device']
device_obj, created = Device.objects.get_or_create(
name=device_name
)
return None if for_user is True else device_obj
This originally worked on my development pc (Widnows), however I wanted to test my site on another pc (Linux/Debian) but ran into an error saying:
这最初在我的开发PC(Widnows)上工作,但我想在另一台PC(Linux/Debian)上测试我的站点,但遇到错误,说:
KeyError at /
'device'
at line device_name = request.COOKIES['device']
Upon further inspection I realized maybe this happens because, in HomeView I try to access device
before the javascript is ran and device is thus set.
在进一步检查后,我意识到这可能是因为在HomeView中,我试图在运行脚本和设置设备之前访问设备。
In homeView, I try to access it in context = get_base_lists(self.request)
line, but device
is set in the return statement, which sends the html to the user, causing the javascript to run and set the device.
在Home View中,我尝试在CONTEXT=GET_BASE_LISTS(self.request)行中访问它,但在返回语句中设置了设备,该语句将html发送给用户,导致运行并设置设备。
How can I get around this? Is there a better way to implement anonymous cart system?
我怎么才能绕过这个问题呢?有没有更好的方式来实现匿名购物车系统?
OS: Debian
Python version: 3.9.2
Django version: 4.0.4
操作系统:Debian Python版本:3.9.2 Django版本:4.0.4
更多回答
优秀答案推荐
I found a couple of small issues related to the codes you shared here.
我发现了几个与您在这里分享的代码相关的小问题。
- The code you provided appears to be mostly correct, but there's a small issue with the document.cookie line. The extra double quotation marks at the end of the line may be causing the issue. Here's the corrected line:
document.cookie = 'device=' + device + '; domain=; path=/';
文件.cookie=‘设备=’+设备+‘;域=;路径=/’;
- When setting the domain attribute for the cookie, you should specify the domain where your Django site is hosted. If you want the cookie to be accessible across all subdomains, you can set it to the root domain like this.
document.cookie = 'device=' + device + '; domain=.yourdomain.com; path=/';
Bookent.cookie=‘Device=’+Device+‘;DOMAIN=.YOURDOMAIN.com;Path=/’;
Modify these first and see what happens.
首先修改这些内容,然后看看会发生什么。
Add this code to your views.py.
将此代码添加到您的views.py中。
def auth_status(request, for_user: bool = True):
if request.user.is_authenticated:
return None if for_user is False else request.user
else:
device_name = request.COOKIES.get('device') # Use get() to avoid KeyError
if device_name is not None:
device_obj, created = Device.objects.get_or_create(
name=device_name
)
return None if for_user is True else device_obj
else:
# Handle the case when 'device' cookie is not present
return None # or raise an exception, depending on your requirements
更多回答
the code you provided seems good, but the problem is that the javascript is not ran, at all. For javascript to run, the view request should successfuly return, but it cannot because it should run the javascript for the device to work....
您提供的代码似乎很好,但问题是根本没有运行该脚本。要运行Java脚本,查看请求应该成功返回,但它不能,因为它应该运行设备工作所需的Java脚本...
What's the detailed error? Can you share the relevant logs here?
详细的错误是什么?你能在这里分享相关日志吗?
views.py", line 35, in auth_status device_name = request.COOKIES['device'] KeyError: 'device'
That's it.
Views.py“,第35行,在auth_atus设备名=quest.COOKIES[‘Device’]KeyError:‘Device’就是这样。
views.py? What is it? Can you copy the code in line 35?
Views.py?那是什么?你能复制第35行的代码吗?
It's provided above, on auth_status
function.
它在上面的auth_status函数中提供。
我是一名优秀的程序员,十分优秀!