You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中基于登录用户名实现数据新增/覆写功能的问题排查

Fix: Overwrite Existing Order for Logged-In User Instead of Creating New Entries

Got it, let's break down what's going wrong and fix this step by step. The main issue is your current code doesn't check if the logged-in user already has an OrderItem record before saving—so it always creates a new entry instead of updating the existing one. Plus, your UpdateOrderView has some critical bugs that prevent it from working as intended.

Key Problems in Your Current Code

  • OrderView: No check for existing user records—just saves the form directly every time, leading to duplicates.
  • UpdateOrderView:
    • username = user.is_authenticated is wrong—is_authenticated returns a boolean, not the actual username.
    • You're trying to use a pk URL parameter, but your logic relies on username, so the pk is irrelevant here.
    • Form initialization for updates is incorrect.

Step-by-Step Fix

1. Add Login Requirement (Critical)

First, make sure only logged-in users can access these views. Import Django's login decorator and apply it to your views.

2. Rewrite OrderView to Handle Create/Update

We'll use Django's get_or_create() method to fetch the existing order for the logged-in user (or create a new one if none exists), then bind it to the form. This way, submitting the form will either update the existing record or save a new one.

Prevent users from modifying the username field by excluding it from the form—we'll set it programmatically to the logged-in user's username to avoid tampering.

Updated Code

views.py

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from .models import OrderItem
from .forms import OrderForm  # Make sure you have this imported

@login_required  # Ensures only logged-in users can access this
def OrderView(request):
    # Get the current logged-in user's username
    current_user = request.user
    # Fetch existing order for the user, or create a blank one if none exists
    order, was_created = OrderItem.objects.get_or_create(username=current_user.username)
    
    # Initialize form with the existing order (or new blank instance)
    form = OrderForm(instance=order)
    
    if request.method == 'POST':
        # Bind POST data to the existing order instance
        form = OrderForm(request.POST, instance=order)
        if form.is_valid():
            # Save the form—this will update the existing record or create a new one
            form.save()
            return redirect('order-page')  # Redirect back to the order page
    
    context = {'form': form}
    # Note: Remove the leading slash from the template path—it should be relative to your templates folder
    return render(request, 'order_info.html', context)

# If you still need a dedicated update view (optional, since OrderView handles both now)
@login_required
def UpdateOrderView(request):
    current_user = request.user
    try:
        order = OrderItem.objects.get(username=current_user.username)
    except OrderItem.DoesNotExist:
        # If no order exists for the user, redirect to create it
        return redirect('order-page')
    
    if request.method == 'POST':
        form = OrderForm(request.POST, instance=order)
        if form.is_valid():
            form.save()
            return redirect('order-page')
    else:
        form = OrderForm(instance=order)
    
    context = {'form': form}
    return render(request, 'order_info.html', context)

forms.py (Add this if you haven't already)

from django import forms
from .models import OrderItem

class OrderForm(forms.ModelForm):
    class Meta:
        model = OrderItem
        # Exclude username so users can't edit it—we set it via the view
        exclude = ['username']
        # Or specify fields explicitly if you prefer:
        # fields = ['first_name', 'last_name', 'vendor_name', 'menu_name', 'note']

urls.py (Adjust to remove unnecessary pk parameter)

from django.urls import path
from . import views

urlpatterns = [
    path("order_info", views.OrderView, name="order-page"),
    # If you keep the update view, remove the pk since we use username
    path("order_update", views.UpdateOrderView, name="order-update"),
]

Why This Works

  • get_or_create(): This method safely retrieves the existing OrderItem for the logged-in user, or creates a new blank instance if none exists.
  • Form Binding: By passing instance=order to the form, Django knows to update that specific record instead of creating a new one when form.save() is called.
  • Login Protection: The @login_required decorator ensures we always have a valid logged-in user to fetch the username from.

内容的提问来源于stack exchange,提问作者D C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 18:32:52