Django дублирует URL-адреса

#django #url #duplicates

#django #url #дубликаты

Вопрос:

Я новичок в Django. Во время работы над моим проектом, когда я хочу перейти к следующей странице, он генерирует дубликат URL. Вот мой URL-адрес домашней страницы: http://127.0.0.1:8000/

Если я хочу просмотреть профиль конкретного клиента, я ожидаю, что URL-адрес должен быть таким: http://127.0.0.1:8000/customer/1/

Но я получаю это: http://127.0.0.1:8000/customer/customer/1/

Я был бы признателен, если бы кто-нибудь мог мне помочь, я нуб.

Вот мой urls.py:

 from . import views

urlpatterns = [
    path('', views.home, name = 'home'),
    path('products/', views.products, name = 'product'),
    path('customer/<str:pk>/', views.customer, name= 'customer'),
    path('create_order/<str:pk>/', views.createOrder, name = 'create_order'),
    path('update_order/<str:pk>/', views.updateOrder, name = 'update_order'),
    path('delete_order/<str:pk>/', views.deleteOrder, name = 'delete_order'),
]
 

Мой views.py:

 from django.http import HttpResponse
from django.forms import inlineformset_factory
from django.urls import reverse
from .models import *
from .forms import OrderForm


def home(request):
    orders = Order.objects.all()
    customers = Customer.objects.all()
    total_customers = customers.count()

    total_orders = orders.count()
    delivered = orders.filter(status='Delivered').count()
    pending = orders.filter(status='Pending').count()

    context = {'orders':orders, 'customers':customers,
    'total_orders':total_orders,'delivered':delivered,
    'pending':pending}

    return render(request, 'accounts/dashboard.html', context)

def products(request):
    products = Product.objects.all()

    return render(request, 'accounts/products.html', {'products':products})

def customer(request, pk):
    customers = Customer.objects.all()
    customer = Customer.objects.get(id=pk)
    orders = customer.order_set.all()
    orders_count = orders.count
    context = {'customer':customer, 'orders':orders, 'orders_count': orders_count}
    return render(request, 'accounts/customer.html', context) 

def createOrder(request, pk):
    OrderFormSet = inlineformset_factory(Customer, Order, fields=('product', 'status'), extra=10)
    customer = Customer.objects.get(id=pk)
    formset = OrderFormSet(queryset =Order.objects.none(), instance=customer)
    if request.method == 'POST':
        formset = OrderFormSet(request.POST, instance=customer)
        if formset.is_valid():
            formset.save()
            return redirect('/')
    
    context = {'formset': formset}
    return render(request, 'accounts/order_form.html', context)


def updateOrder(request, pk):

    order = Order.objects.get(id=pk)
    form = OrderForm(instance=order)
    
    if request.method == 'POST':
        form = OrderForm(request.POST, instance=order)
        if form.is_valid():
            form.save()
            return redirect('/')

    context = {'form': form}
    return render(request, 'accounts/order_form.html', context)


def deleteOrder(request, pk):
    order = Order.objects.get(id=pk)

    if request.method == "POST":
        order.delete()
        return redirect('/')

    context = {'item': order}
    return render (request, 'accounts/delete.html', context)
 

Мой models.py:

 
# Create your models here.

class Customer(models.Model):
    name = models.CharField(max_length=200, null=True)
    phone = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200, null=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)

    def __str__(self):
        return self.name

class Tag(models.Model):
    name = models.CharField(max_length=200, null=True)

    def __str__(self):
        return self.name

class Product(models.Model):
    CATEGORY = (
            ('Indoor', 'Indoor'),
            ('Out Door', 'Out Door'),
            ) 

    name = models.CharField(max_length=200, null=True)
    price = models.FloatField(null=True)
    category = models.CharField(max_length=200, null=True, choices=CATEGORY)
    description = models.CharField(max_length=200, null=True, blank=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    tags = models.ManyToManyField(Tag)

    def __str__(self):
        return self.name

class Order(models.Model):
    STATUS = (
            ('Pending', 'Pending'),
            ('Out for delivery', 'Out for delivery'),
            ('Delivered', 'Delivered'),
            )

    customer = models.ForeignKey(Customer, null=True, on_delete= models.SET_NULL)
    product = models.ForeignKey(Product, null=True, on_delete= models.SET_NULL)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    status = models.CharField(max_length=200, null=True, choices=STATUS)

    def __str__(self):
        return self.product.name
 

My settings.py:

 import os

ALLOWED_HOSTS = []

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'accounts',
]
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'cmp.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'cmp.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Dhaka'

USE_I18N = True

USE_L10N = True

USE_TZ = True

STATIC_URL = '/static/'
MEDIA_URL = '/images/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]
 

Мой dashboard.html:

 
{% block content %}

{% include 'accounts/status.html' %}
<br>

<div class="row">
    <div class="col-md-5">
        <h5>CUSTOMERS:</h5>
        <hr>
        <div class="card card-body">
            <a class="btn btn-primary  btn-sm btn-block" href="">Create Customer</a>
            <table class="table table-sm">
                <tr>
                    <td></td>
                    <td></td>
                    <th>Customer</th>
                    <th>Phone</th>
                </tr>
                {% for customer in customers %}
                    <tr>
                        <td> <a class="btn btn-primary btn-sm btn-block" href="{% url 'customer' customer.id %}">View</a></td>
                        <td></td>
                        <td>{{customer.name}}</td>
                        <td>{{customer.phone}}</td>
                    </tr>
                {% endfor %}
                

            </table>
        </div>
    </div>

    <div class="col-md-7">
        <h5>LAST SOME ORDERS</h5>
        <hr>
        <div class="card card-body">
            <table class="table table-sm">
                <tr>
                    <th>Customer</th>
                    <th>Product</th>
                    <th>Date Orderd</th>
                    <th>Status</th>
                    <th>Update</th>
                    <th>Remove</th>
                </tr>

                {% for order in orders %}
                    <tr>
                        <td>{{order.customer}}</td>
                        <td>{{order.product}}</td>
                        <td>{{order.date_created}}</td>
                        <td>{{order.status}}</td>
                        <td><a class="btn btn-sm btn-info" href="{% url 'update_order' order.id %}">Update</a></td>
                        <td><a class="btn btn-sm btn-danger" href="{% url 'delete_order' order.id %}">Remove</a></td>
                    </tr>
                {% endfor %}
        
            </table>
        </div>
    </div>

</div>

{% endblock %}
 

И мой customer.html:

 
{% block content %}

<br>

<div class="row">
    <div class="col-md">
        <div class="card card-body">
            <h5>Customer:</h5>
            <hr>
            <a class="btn btn-outline-success btn-sm btn-block" href="{% url 'create_order' customer.id %}">Place Order</a>
            <a class="btn btn-outline-info btn-sm btn-block" href="">Update Customer</a>
            <a class="btn btn-outline-danger btn-sm btn-block" href="">Delete Customer</a>

        </div>
    </div>

    <div class="col-md">
        <div class="card card-body">
            <h5>Contact Information</h5>
            <hr>
            <p>Email: {{customer.email}}</p>
            <p>Phone: {{customer.phone}}</p>
        </div>
    </div>

    <div class="col-md">
        <div class="card card-body">
            <h5>Total Orders</h5>
            <hr>
            <h1 style="text-align: center;padding: 10px">{{orders_count}}</h1>
        </div>
    </div>
</div>


<br>
<div class="row">
    <div class="col">
        <div class="card card-body">
            <form method="get">

            <button class="btn btn-primary" type="submit">Search</button>
          </form>
        </div>
    </div>
    
</div>
<br>

<div class="row">
    <div class="col-md">
        <div class="card card-body">
            <table class="table table-sm">
                <tr>
                    <th>Product</th>
                    <th>Category</th>
                    <th>Date Orderd</th>
                    <th>Status</th>
                    <th>Update</th>
                    <th>Remove</th>
                </tr>

                {% for order in orders %}
                    <tr>
                        <td>{{order.product}}</td>
                        <td>{{order.product.category}}</td>
                        <td>{{order.date_created}}</td>
                        <td>{{order.status}}</td>
                        <td><a class="btn btn-sm btn-info" href="{% url 'update_order' order.id %}">Update</a></td>
                        <td><a class="btn btn-sm btn-danger" href="{% url 'delete_order' order.id %}">Remove</a></td>
                    </tr>
                {% endfor %}
            </table>
        </div>
    </div>
</div

{% endblock %}
 

Комментарии:

1. Можете ли вы также поместить файл настроек?

2. Пожалуйста, проверьте еще раз. Я добавил settings.py досье.

Ответ №1:

Скорее всего, у вас есть что-то подобное в вашем основном urls.py

 urlpatterns = [
    path('admin/', admin.site.urls),
    path('customer/', include('accounts.urls')),
 # other...
 

заменить на

 urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('accounts.urls')), 
 # other ... 
 

Обратите внимание , что нет customer в path . Таким образом, вы решите свою customer/customer/ проблему.

Комментарии:

1. Это также сработало для меня. И если я сохраню главное urls.py без изменений и вносить изменения в setting.py замена ROOT_URLCONF=»cmp.urls» на ROOT_URLCONF=»accounts.urls», это также работает. Я не знаю, что является хорошей практикой.

2. постарайтесь не менять на ROOT_URLCONF, потому что позже вы добавите дополнительные apps , верно? например, и т.д. products ваш ROOT_URLCONF уровень всегда должен быть вашим project уровнем, а не app уровнем.

3. Кроме того, вы должны ограничить accounts app для user связанных вещей, таких как sign up , log in , profile и т.д., и переместить products связанные с ними в новый app . Таким образом, вы делаете свое приложение django модульным и переносимым. Ваш accounts может быть использован в вашем следующем проекте о чем-то другом, например, о проекте блога.

4. Спасибо, брат, я понял твою точку зрения о ROOT_URLCONF. И я буду работать над signup , login и т.д. сейчас. Перед этим я хотел быть уверенным, что все идет нормально.

Ответ №2:

Вы можете найти место, где отображается неправильный URL-адрес, и посмотреть, работает ли функция url ({% url … используется %}) или жестко закодированный html. Если там используется жестко закодированный html, не забудьте добавить косую черту в начале

Ответ №3:

Название вашего приложения для urls.py кажется, это учетные записи (я предполагаю это, потому что шаблоны берутся из учетных записей / …). Но в настройках вы определяете ROOT_URLCONF=»cmd.urls». Возможно ли, что urls.py то, что вы опубликовали, не является корневым, а импортировано корневым urls.py с путем к клиенту? Просто возможное предположение

Комментарии:

1. Большое спасибо. Это сработало для меня! Еще раз спасибо, брат.

2. Если я оставлю ROOT_URLCONF без изменений и внесу изменения в main urls.py path(' ', include('accounts.urls')) заменяя path('customer/', include('accounts.urls')) , это тоже работает. Я не знаю, какая практика лучше всего подходит.

3. Вопрос только в том, как вы хотели бы, чтобы древовидная структура вашего приложения была видна пользователю… это похоже на организацию его в виртуальные папки